import abc
import builtins
import datetime
import enum
import typing

import jsii
import publication
import typing_extensions

from typeguard import check_type

from .._jsii import *

import cdk8s
import constructs


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Affinity",
    jsii_struct_bases=[],
    name_mapping={
        "node_affinity": "nodeAffinity",
        "pod_affinity": "podAffinity",
        "pod_anti_affinity": "podAntiAffinity",
    },
)
class Affinity:
    def __init__(
        self,
        *,
        node_affinity: typing.Optional[typing.Union["NodeAffinity", typing.Dict[str, typing.Any]]] = None,
        pod_affinity: typing.Optional[typing.Union["PodAffinity", typing.Dict[str, typing.Any]]] = None,
        pod_anti_affinity: typing.Optional[typing.Union["PodAntiAffinity", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Affinity is a group of affinity scheduling rules.

        :param node_affinity: Describes node affinity scheduling rules for the pod.
        :param pod_affinity: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).
        :param pod_anti_affinity: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).

        :schema: io.k8s.api.core.v1.Affinity
        '''
        if isinstance(node_affinity, dict):
            node_affinity = NodeAffinity(**node_affinity)
        if isinstance(pod_affinity, dict):
            pod_affinity = PodAffinity(**pod_affinity)
        if isinstance(pod_anti_affinity, dict):
            pod_anti_affinity = PodAntiAffinity(**pod_anti_affinity)
        if __debug__:
            def stub(
                *,
                node_affinity: typing.Optional[typing.Union[NodeAffinity, typing.Dict[str, typing.Any]]] = None,
                pod_affinity: typing.Optional[typing.Union[PodAffinity, typing.Dict[str, typing.Any]]] = None,
                pod_anti_affinity: typing.Optional[typing.Union[PodAntiAffinity, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument node_affinity", value=node_affinity, expected_type=type_hints["node_affinity"])
            check_type(argname="argument pod_affinity", value=pod_affinity, expected_type=type_hints["pod_affinity"])
            check_type(argname="argument pod_anti_affinity", value=pod_anti_affinity, expected_type=type_hints["pod_anti_affinity"])
        self._values: typing.Dict[str, typing.Any] = {}
        if node_affinity is not None:
            self._values["node_affinity"] = node_affinity
        if pod_affinity is not None:
            self._values["pod_affinity"] = pod_affinity
        if pod_anti_affinity is not None:
            self._values["pod_anti_affinity"] = pod_anti_affinity

    @builtins.property
    def node_affinity(self) -> typing.Optional["NodeAffinity"]:
        '''Describes node affinity scheduling rules for the pod.

        :schema: io.k8s.api.core.v1.Affinity#nodeAffinity
        '''
        result = self._values.get("node_affinity")
        return typing.cast(typing.Optional["NodeAffinity"], result)

    @builtins.property
    def pod_affinity(self) -> typing.Optional["PodAffinity"]:
        '''Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).

        :schema: io.k8s.api.core.v1.Affinity#podAffinity
        '''
        result = self._values.get("pod_affinity")
        return typing.cast(typing.Optional["PodAffinity"], result)

    @builtins.property
    def pod_anti_affinity(self) -> typing.Optional["PodAntiAffinity"]:
        '''Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).

        :schema: io.k8s.api.core.v1.Affinity#podAntiAffinity
        '''
        result = self._values.get("pod_anti_affinity")
        return typing.cast(typing.Optional["PodAntiAffinity"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Affinity(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AggregationRule",
    jsii_struct_bases=[],
    name_mapping={"cluster_role_selectors": "clusterRoleSelectors"},
)
class AggregationRule:
    def __init__(
        self,
        *,
        cluster_role_selectors: typing.Optional[typing.Sequence[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''AggregationRule describes how to locate ClusterRoles to aggregate into the ClusterRole.

        :param cluster_role_selectors: ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules. If any of the selectors match, then the ClusterRole's permissions will be added

        :schema: io.k8s.api.rbac.v1.AggregationRule
        '''
        if __debug__:
            def stub(
                *,
                cluster_role_selectors: typing.Optional[typing.Sequence[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument cluster_role_selectors", value=cluster_role_selectors, expected_type=type_hints["cluster_role_selectors"])
        self._values: typing.Dict[str, typing.Any] = {}
        if cluster_role_selectors is not None:
            self._values["cluster_role_selectors"] = cluster_role_selectors

    @builtins.property
    def cluster_role_selectors(self) -> typing.Optional[typing.List["LabelSelector"]]:
        '''ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules.

        If any of the selectors match, then the ClusterRole's permissions will be added

        :schema: io.k8s.api.rbac.v1.AggregationRule#clusterRoleSelectors
        '''
        result = self._values.get("cluster_role_selectors")
        return typing.cast(typing.Optional[typing.List["LabelSelector"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AggregationRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AllowedCsiDriverV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class AllowedCsiDriverV1Beta1:
    def __init__(self, *, name: builtins.str) -> None:
        '''AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used.

        :param name: Name is the registered name of the CSI driver.

        :schema: io.k8s.api.policy.v1beta1.AllowedCSIDriver
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the registered name of the CSI driver.

        :schema: io.k8s.api.policy.v1beta1.AllowedCSIDriver#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AllowedCsiDriverV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AllowedFlexVolumeV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"driver": "driver"},
)
class AllowedFlexVolumeV1Beta1:
    def __init__(self, *, driver: builtins.str) -> None:
        '''AllowedFlexVolume represents a single Flexvolume that is allowed to be used.

        :param driver: driver is the name of the Flexvolume driver.

        :schema: io.k8s.api.policy.v1beta1.AllowedFlexVolume
        '''
        if __debug__:
            def stub(*, driver: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument driver", value=driver, expected_type=type_hints["driver"])
        self._values: typing.Dict[str, typing.Any] = {
            "driver": driver,
        }

    @builtins.property
    def driver(self) -> builtins.str:
        '''driver is the name of the Flexvolume driver.

        :schema: io.k8s.api.policy.v1beta1.AllowedFlexVolume#driver
        '''
        result = self._values.get("driver")
        assert result is not None, "Required property 'driver' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AllowedFlexVolumeV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AllowedHostPathV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"path_prefix": "pathPrefix", "read_only": "readOnly"},
)
class AllowedHostPathV1Beta1:
    def __init__(
        self,
        *,
        path_prefix: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''AllowedHostPath defines the host volume conditions that will be enabled by a policy for pods to use.

        It requires the path prefix to be defined.

        :param path_prefix: pathPrefix is the path prefix that the host volume must match. It does not support ``*``. Trailing slashes are trimmed when validating the path prefix with a host path. Examples: ``/foo`` would allow ``/foo``, ``/foo/`` and ``/foo/bar`` ``/foo`` would not allow ``/food`` or ``/etc/foo``
        :param read_only: when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly.

        :schema: io.k8s.api.policy.v1beta1.AllowedHostPath
        '''
        if __debug__:
            def stub(
                *,
                path_prefix: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path_prefix", value=path_prefix, expected_type=type_hints["path_prefix"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {}
        if path_prefix is not None:
            self._values["path_prefix"] = path_prefix
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def path_prefix(self) -> typing.Optional[builtins.str]:
        '''pathPrefix is the path prefix that the host volume must match.

        It does not support ``*``. Trailing slashes are trimmed when validating the path prefix with a host path.

        Examples: ``/foo`` would allow ``/foo``, ``/foo/`` and ``/foo/bar`` ``/foo`` would not allow ``/food`` or ``/etc/foo``

        :schema: io.k8s.api.policy.v1beta1.AllowedHostPath#pathPrefix
        '''
        result = self._values.get("path_prefix")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly.

        :schema: io.k8s.api.policy.v1beta1.AllowedHostPath#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AllowedHostPathV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ApiServiceSpec",
    jsii_struct_bases=[],
    name_mapping={
        "group_priority_minimum": "groupPriorityMinimum",
        "version_priority": "versionPriority",
        "ca_bundle": "caBundle",
        "group": "group",
        "insecure_skip_tls_verify": "insecureSkipTlsVerify",
        "service": "service",
        "version": "version",
    },
)
class ApiServiceSpec:
    def __init__(
        self,
        *,
        group_priority_minimum: jsii.Number,
        version_priority: jsii.Number,
        ca_bundle: typing.Optional[builtins.str] = None,
        group: typing.Optional[builtins.str] = None,
        insecure_skip_tls_verify: typing.Optional[builtins.bool] = None,
        service: typing.Optional[typing.Union["ServiceReference", typing.Dict[str, typing.Any]]] = None,
        version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''APIServiceSpec contains information for locating and communicating with a server.

        Only https is supported, though you are able to disable certificate verification.

        :param group_priority_minimum: GroupPriorityMininum is the priority this group should have at least. Higher priority means that the group is preferred by clients over lower priority ones. Note that other versions of this group might specify even higher GroupPriorityMininum values such that the whole group gets a higher priority. The primary sort is based on GroupPriorityMinimum, ordered highest number to lowest (20 before 10). The secondary sort is based on the alphabetical comparison of the name of the object. (v1.bar before v1.foo) We'd recommend something like: *.k8s.io (except extensions) at 18000 and PaaSes (OpenShift, Deis) are recommended to be in the 2000s
        :param version_priority: VersionPriority controls the ordering of this API version inside of its group. Must be greater than zero. The primary sort is based on VersionPriority, ordered highest to lowest (20 before 10). Since it's inside of a group, the number can be small, probably in the 10s. In case of equal version priorities, the version string will be used to compute the order inside a group. If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version), then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing major version, then minor version. An example sorted list of versions: v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.
        :param ca_bundle: CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate. If unspecified, system trust roots on the apiserver are used.
        :param group: Group is the API group name this server hosts.
        :param insecure_skip_tls_verify: InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server. This is strongly discouraged. You should use the CABundle instead.
        :param service: Service is a reference to the service for this API server. It must communicate on port 443. If the Service is nil, that means the handling for the API groupversion is handled locally on this server. The call will simply delegate to the normal handler chain to be fulfilled.
        :param version: Version is the API version this server hosts. For example, "v1"

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec
        '''
        if isinstance(service, dict):
            service = ServiceReference(**service)
        if __debug__:
            def stub(
                *,
                group_priority_minimum: jsii.Number,
                version_priority: jsii.Number,
                ca_bundle: typing.Optional[builtins.str] = None,
                group: typing.Optional[builtins.str] = None,
                insecure_skip_tls_verify: typing.Optional[builtins.bool] = None,
                service: typing.Optional[typing.Union[ServiceReference, typing.Dict[str, typing.Any]]] = None,
                version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument group_priority_minimum", value=group_priority_minimum, expected_type=type_hints["group_priority_minimum"])
            check_type(argname="argument version_priority", value=version_priority, expected_type=type_hints["version_priority"])
            check_type(argname="argument ca_bundle", value=ca_bundle, expected_type=type_hints["ca_bundle"])
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument insecure_skip_tls_verify", value=insecure_skip_tls_verify, expected_type=type_hints["insecure_skip_tls_verify"])
            check_type(argname="argument service", value=service, expected_type=type_hints["service"])
            check_type(argname="argument version", value=version, expected_type=type_hints["version"])
        self._values: typing.Dict[str, typing.Any] = {
            "group_priority_minimum": group_priority_minimum,
            "version_priority": version_priority,
        }
        if ca_bundle is not None:
            self._values["ca_bundle"] = ca_bundle
        if group is not None:
            self._values["group"] = group
        if insecure_skip_tls_verify is not None:
            self._values["insecure_skip_tls_verify"] = insecure_skip_tls_verify
        if service is not None:
            self._values["service"] = service
        if version is not None:
            self._values["version"] = version

    @builtins.property
    def group_priority_minimum(self) -> jsii.Number:
        '''GroupPriorityMininum is the priority this group should have at least.

        Higher priority means that the group is preferred by clients over lower priority ones. Note that other versions of this group might specify even higher GroupPriorityMininum values such that the whole group gets a higher priority. The primary sort is based on GroupPriorityMinimum, ordered highest number to lowest (20 before 10). The secondary sort is based on the alphabetical comparison of the name of the object.  (v1.bar before v1.foo) We'd recommend something like: *.k8s.io (except extensions) at 18000 and PaaSes (OpenShift, Deis) are recommended to be in the 2000s

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#groupPriorityMinimum
        '''
        result = self._values.get("group_priority_minimum")
        assert result is not None, "Required property 'group_priority_minimum' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def version_priority(self) -> jsii.Number:
        '''VersionPriority controls the ordering of this API version inside of its group.

        Must be greater than zero. The primary sort is based on VersionPriority, ordered highest to lowest (20 before 10). Since it's inside of a group, the number can be small, probably in the 10s. In case of equal version priorities, the version string will be used to compute the order inside a group. If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version), then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing major version, then minor version. An example sorted list of versions: v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#versionPriority
        '''
        result = self._values.get("version_priority")
        assert result is not None, "Required property 'version_priority' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def ca_bundle(self) -> typing.Optional[builtins.str]:
        '''CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate.

        If unspecified, system trust roots on the apiserver are used.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#caBundle
        '''
        result = self._values.get("ca_bundle")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def group(self) -> typing.Optional[builtins.str]:
        '''Group is the API group name this server hosts.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#group
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def insecure_skip_tls_verify(self) -> typing.Optional[builtins.bool]:
        '''InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server.

        This is strongly discouraged.  You should use the CABundle instead.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#insecureSkipTLSVerify
        '''
        result = self._values.get("insecure_skip_tls_verify")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def service(self) -> typing.Optional["ServiceReference"]:
        '''Service is a reference to the service for this API server.

        It must communicate on port 443. If the Service is nil, that means the handling for the API groupversion is handled locally on this server. The call will simply delegate to the normal handler chain to be fulfilled.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#service
        '''
        result = self._values.get("service")
        return typing.cast(typing.Optional["ServiceReference"], result)

    @builtins.property
    def version(self) -> typing.Optional[builtins.str]:
        '''Version is the API version this server hosts.

        For example, "v1"

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec#version
        '''
        result = self._values.get("version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ApiServiceSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AwsElasticBlockStoreVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "volume_id": "volumeId",
        "fs_type": "fsType",
        "partition": "partition",
        "read_only": "readOnly",
    },
)
class AwsElasticBlockStoreVolumeSource:
    def __init__(
        self,
        *,
        volume_id: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        partition: typing.Optional[jsii.Number] = None,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Represents a Persistent Disk resource in AWS.

        An AWS EBS disk must exist before mounting to a container. The disk must also be in the same AWS zone as the kubelet. An AWS EBS disk can only be mounted as read/write once. AWS EBS volumes support ownership management and SELinux relabeling.

        :param volume_id: Unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
        :param fs_type: Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
        :param partition: The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty).
        :param read_only: Specify "true" to force and set the ReadOnly property in VolumeMounts to "true". If omitted, the default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

        :schema: io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                volume_id: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                partition: typing.Optional[jsii.Number] = None,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument volume_id", value=volume_id, expected_type=type_hints["volume_id"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument partition", value=partition, expected_type=type_hints["partition"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "volume_id": volume_id,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if partition is not None:
            self._values["partition"] = partition
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def volume_id(self) -> builtins.str:
        '''Unique ID of the persistent disk resource in AWS (Amazon EBS volume).

        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

        :schema: io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource#volumeID
        '''
        result = self._values.get("volume_id")
        assert result is not None, "Required property 'volume_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type of the volume that you want to mount.

        Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

        :schema: io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def partition(self) -> typing.Optional[jsii.Number]:
        '''The partition in the volume that you want to mount.

        If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty).

        :schema: io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource#partition
        '''
        result = self._values.get("partition")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Specify "true" to force and set the ReadOnly property in VolumeMounts to "true".

        If omitted, the default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

        :schema: io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AwsElasticBlockStoreVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AzureDiskVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "disk_name": "diskName",
        "disk_uri": "diskUri",
        "caching_mode": "cachingMode",
        "fs_type": "fsType",
        "kind": "kind",
        "read_only": "readOnly",
    },
)
class AzureDiskVolumeSource:
    def __init__(
        self,
        *,
        disk_name: builtins.str,
        disk_uri: builtins.str,
        caching_mode: typing.Optional[builtins.str] = None,
        fs_type: typing.Optional[builtins.str] = None,
        kind: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.

        :param disk_name: The Name of the data disk in the blob storage.
        :param disk_uri: The URI the data disk in the blob storage.
        :param caching_mode: Host Caching mode: None, Read Only, Read Write.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
        :param kind: Expected values Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                disk_name: builtins.str,
                disk_uri: builtins.str,
                caching_mode: typing.Optional[builtins.str] = None,
                fs_type: typing.Optional[builtins.str] = None,
                kind: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument disk_name", value=disk_name, expected_type=type_hints["disk_name"])
            check_type(argname="argument disk_uri", value=disk_uri, expected_type=type_hints["disk_uri"])
            check_type(argname="argument caching_mode", value=caching_mode, expected_type=type_hints["caching_mode"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "disk_name": disk_name,
            "disk_uri": disk_uri,
        }
        if caching_mode is not None:
            self._values["caching_mode"] = caching_mode
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if kind is not None:
            self._values["kind"] = kind
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def disk_name(self) -> builtins.str:
        '''The Name of the data disk in the blob storage.

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource#diskName
        '''
        result = self._values.get("disk_name")
        assert result is not None, "Required property 'disk_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def disk_uri(self) -> builtins.str:
        '''The URI the data disk in the blob storage.

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource#diskURI
        '''
        result = self._values.get("disk_uri")
        assert result is not None, "Required property 'disk_uri' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def caching_mode(self) -> typing.Optional[builtins.str]:
        '''Host Caching mode: None, Read Only, Read Write.

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource#cachingMode
        '''
        result = self._values.get("caching_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def kind(self) -> typing.Optional[builtins.str]:
        '''Expected values Shared: multiple blob disks per storage account  Dedicated: single blob disk per storage account  Managed: azure managed data disk (only in managed availability set).

        defaults to shared

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource#kind
        '''
        result = self._values.get("kind")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.AzureDiskVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AzureDiskVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AzureFilePersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "secret_name": "secretName",
        "share_name": "shareName",
        "read_only": "readOnly",
        "secret_namespace": "secretNamespace",
    },
)
class AzureFilePersistentVolumeSource:
    def __init__(
        self,
        *,
        secret_name: builtins.str,
        share_name: builtins.str,
        read_only: typing.Optional[builtins.bool] = None,
        secret_namespace: typing.Optional[builtins.str] = None,
    ) -> None:
        '''AzureFile represents an Azure File Service mount on the host and bind mount to the pod.

        :param secret_name: the name of secret that contains Azure Storage Account Name and Key.
        :param share_name: Share Name.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param secret_namespace: the namespace of the secret that contains Azure Storage Account Name and Key default is the same as the Pod.

        :schema: io.k8s.api.core.v1.AzureFilePersistentVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                secret_name: builtins.str,
                share_name: builtins.str,
                read_only: typing.Optional[builtins.bool] = None,
                secret_namespace: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
            check_type(argname="argument share_name", value=share_name, expected_type=type_hints["share_name"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_namespace", value=secret_namespace, expected_type=type_hints["secret_namespace"])
        self._values: typing.Dict[str, typing.Any] = {
            "secret_name": secret_name,
            "share_name": share_name,
        }
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_namespace is not None:
            self._values["secret_namespace"] = secret_namespace

    @builtins.property
    def secret_name(self) -> builtins.str:
        '''the name of secret that contains Azure Storage Account Name and Key.

        :schema: io.k8s.api.core.v1.AzureFilePersistentVolumeSource#secretName
        '''
        result = self._values.get("secret_name")
        assert result is not None, "Required property 'secret_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def share_name(self) -> builtins.str:
        '''Share Name.

        :schema: io.k8s.api.core.v1.AzureFilePersistentVolumeSource#shareName
        '''
        result = self._values.get("share_name")
        assert result is not None, "Required property 'share_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.AzureFilePersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_namespace(self) -> typing.Optional[builtins.str]:
        '''the namespace of the secret that contains Azure Storage Account Name and Key default is the same as the Pod.

        :schema: io.k8s.api.core.v1.AzureFilePersistentVolumeSource#secretNamespace
        '''
        result = self._values.get("secret_namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AzureFilePersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.AzureFileVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "secret_name": "secretName",
        "share_name": "shareName",
        "read_only": "readOnly",
    },
)
class AzureFileVolumeSource:
    def __init__(
        self,
        *,
        secret_name: builtins.str,
        share_name: builtins.str,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''AzureFile represents an Azure File Service mount on the host and bind mount to the pod.

        :param secret_name: the name of secret that contains Azure Storage Account Name and Key.
        :param share_name: Share Name.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.AzureFileVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                secret_name: builtins.str,
                share_name: builtins.str,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
            check_type(argname="argument share_name", value=share_name, expected_type=type_hints["share_name"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "secret_name": secret_name,
            "share_name": share_name,
        }
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def secret_name(self) -> builtins.str:
        '''the name of secret that contains Azure Storage Account Name and Key.

        :schema: io.k8s.api.core.v1.AzureFileVolumeSource#secretName
        '''
        result = self._values.get("secret_name")
        assert result is not None, "Required property 'secret_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def share_name(self) -> builtins.str:
        '''Share Name.

        :schema: io.k8s.api.core.v1.AzureFileVolumeSource#shareName
        '''
        result = self._values.get("share_name")
        assert result is not None, "Required property 'share_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.AzureFileVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AzureFileVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.BoundObjectReference",
    jsii_struct_bases=[],
    name_mapping={
        "api_version": "apiVersion",
        "kind": "kind",
        "name": "name",
        "uid": "uid",
    },
)
class BoundObjectReference:
    def __init__(
        self,
        *,
        api_version: typing.Optional[builtins.str] = None,
        kind: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        uid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''BoundObjectReference is a reference to an object that a token is bound to.

        :param api_version: API version of the referent.
        :param kind: Kind of the referent. Valid kinds are 'Pod' and 'Secret'.
        :param name: Name of the referent.
        :param uid: UID of the referent.

        :schema: io.k8s.api.authentication.v1.BoundObjectReference
        '''
        if __debug__:
            def stub(
                *,
                api_version: typing.Optional[builtins.str] = None,
                kind: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                uid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
        self._values: typing.Dict[str, typing.Any] = {}
        if api_version is not None:
            self._values["api_version"] = api_version
        if kind is not None:
            self._values["kind"] = kind
        if name is not None:
            self._values["name"] = name
        if uid is not None:
            self._values["uid"] = uid

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''API version of the referent.

        :schema: io.k8s.api.authentication.v1.BoundObjectReference#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def kind(self) -> typing.Optional[builtins.str]:
        '''Kind of the referent.

        Valid kinds are 'Pod' and 'Secret'.

        :schema: io.k8s.api.authentication.v1.BoundObjectReference#kind
        '''
        result = self._values.get("kind")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        :schema: io.k8s.api.authentication.v1.BoundObjectReference#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''UID of the referent.

        :schema: io.k8s.api.authentication.v1.BoundObjectReference#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "BoundObjectReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Capabilities",
    jsii_struct_bases=[],
    name_mapping={"add": "add", "drop": "drop"},
)
class Capabilities:
    def __init__(
        self,
        *,
        add: typing.Optional[typing.Sequence[builtins.str]] = None,
        drop: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''Adds and removes POSIX capabilities from running containers.

        :param add: Added capabilities.
        :param drop: Removed capabilities.

        :schema: io.k8s.api.core.v1.Capabilities
        '''
        if __debug__:
            def stub(
                *,
                add: typing.Optional[typing.Sequence[builtins.str]] = None,
                drop: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument add", value=add, expected_type=type_hints["add"])
            check_type(argname="argument drop", value=drop, expected_type=type_hints["drop"])
        self._values: typing.Dict[str, typing.Any] = {}
        if add is not None:
            self._values["add"] = add
        if drop is not None:
            self._values["drop"] = drop

    @builtins.property
    def add(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Added capabilities.

        :schema: io.k8s.api.core.v1.Capabilities#add
        '''
        result = self._values.get("add")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def drop(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Removed capabilities.

        :schema: io.k8s.api.core.v1.Capabilities#drop
        '''
        result = self._values.get("drop")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Capabilities(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CephFsPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "monitors": "monitors",
        "path": "path",
        "read_only": "readOnly",
        "secret_file": "secretFile",
        "secret_ref": "secretRef",
        "user": "user",
    },
)
class CephFsPersistentVolumeSource:
    def __init__(
        self,
        *,
        monitors: typing.Sequence[builtins.str],
        path: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_file: typing.Optional[builtins.str] = None,
        secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Ceph Filesystem mount that lasts the lifetime of a pod Cephfs volumes do not support ownership management or SELinux relabeling.

        :param monitors: Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.
        :param path: Optional: Used as the mounted root, rather than the full Ceph tree, default is /.
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
        :param secret_file: Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.
        :param secret_ref: Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
        :param user: Optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = SecretReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                monitors: typing.Sequence[builtins.str],
                path: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_file: typing.Optional[builtins.str] = None,
                secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument monitors", value=monitors, expected_type=type_hints["monitors"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_file", value=secret_file, expected_type=type_hints["secret_file"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "monitors": monitors,
        }
        if path is not None:
            self._values["path"] = path
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_file is not None:
            self._values["secret_file"] = secret_file
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def monitors(self) -> typing.List[builtins.str]:
        '''Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource#monitors
        '''
        result = self._values.get("monitors")
        assert result is not None, "Required property 'monitors' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''Optional: Used as the mounted root, rather than the full Ceph tree, default is /.

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource#path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_file(self) -> typing.Optional[builtins.str]:
        '''Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource#secretFile
        '''
        result = self._values.get("secret_file")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["SecretReference"]:
        '''Optional: SecretRef is reference to the authentication secret for User, default is empty.

        More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''Optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSPersistentVolumeSource#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CephFsPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CephFsVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "monitors": "monitors",
        "path": "path",
        "read_only": "readOnly",
        "secret_file": "secretFile",
        "secret_ref": "secretRef",
        "user": "user",
    },
)
class CephFsVolumeSource:
    def __init__(
        self,
        *,
        monitors: typing.Sequence[builtins.str],
        path: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_file: typing.Optional[builtins.str] = None,
        secret_ref: typing.Optional[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Ceph Filesystem mount that lasts the lifetime of a pod Cephfs volumes do not support ownership management or SELinux relabeling.

        :param monitors: Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.
        :param path: Optional: Used as the mounted root, rather than the full Ceph tree, default is /.
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
        :param secret_file: Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.
        :param secret_ref: Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
        :param user: Optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                monitors: typing.Sequence[builtins.str],
                path: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_file: typing.Optional[builtins.str] = None,
                secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument monitors", value=monitors, expected_type=type_hints["monitors"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_file", value=secret_file, expected_type=type_hints["secret_file"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "monitors": monitors,
        }
        if path is not None:
            self._values["path"] = path
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_file is not None:
            self._values["secret_file"] = secret_file
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def monitors(self) -> typing.List[builtins.str]:
        '''Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSVolumeSource#monitors
        '''
        result = self._values.get("monitors")
        assert result is not None, "Required property 'monitors' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''Optional: Used as the mounted root, rather than the full Ceph tree, default is /.

        :schema: io.k8s.api.core.v1.CephFSVolumeSource#path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.CephFSVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_file(self) -> typing.Optional[builtins.str]:
        '''Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSVolumeSource#secretFile
        '''
        result = self._values.get("secret_file")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["LocalObjectReference"]:
        '''Optional: SecretRef is reference to the authentication secret for User, default is empty.

        More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.CephFSVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["LocalObjectReference"], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''Optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it.

        :schema: io.k8s.api.core.v1.CephFSVolumeSource#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CephFsVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CertificateSigningRequestSpec",
    jsii_struct_bases=[],
    name_mapping={
        "request": "request",
        "signer_name": "signerName",
        "expiration_seconds": "expirationSeconds",
        "extra": "extra",
        "groups": "groups",
        "uid": "uid",
        "usages": "usages",
        "username": "username",
    },
)
class CertificateSigningRequestSpec:
    def __init__(
        self,
        *,
        request: builtins.str,
        signer_name: builtins.str,
        expiration_seconds: typing.Optional[jsii.Number] = None,
        extra: typing.Optional[typing.Mapping[builtins.str, typing.Sequence[builtins.str]]] = None,
        groups: typing.Optional[typing.Sequence[builtins.str]] = None,
        uid: typing.Optional[builtins.str] = None,
        usages: typing.Optional[typing.Sequence[builtins.str]] = None,
        username: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CertificateSigningRequestSpec contains the certificate request.

        :param request: request contains an x509 certificate signing request encoded in a "CERTIFICATE REQUEST" PEM block. When serialized as JSON or YAML, the data is additionally base64-encoded.
        :param signer_name: signerName indicates the requested signer, and is a qualified name. List/watch requests for CertificateSigningRequests can filter on this field using a "spec.signerName=NAME" fieldSelector. Well-known Kubernetes signers are: 1. "kubernetes.io/kube-apiserver-client": issues client certificates that can be used to authenticate to kube-apiserver. Requests for this signer are never auto-approved by kube-controller-manager, can be issued by the "csrsigning" controller in kube-controller-manager. 2. "kubernetes.io/kube-apiserver-client-kubelet": issues client certificates that kubelets use to authenticate to kube-apiserver. Requests for this signer can be auto-approved by the "csrapproving" controller in kube-controller-manager, and can be issued by the "csrsigning" controller in kube-controller-manager. 3. "kubernetes.io/kubelet-serving" issues serving certificates that kubelets use to serve TLS endpoints, which kube-apiserver can connect to securely. Requests for this signer are never auto-approved by kube-controller-manager, and can be issued by the "csrsigning" controller in kube-controller-manager. More details are available at https://k8s.io/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers Custom signerNames can also be specified. The signer defines: 1. Trust distribution: how trust (CA bundles) are distributed. 2. Permitted subjects: and behavior when a disallowed subject is requested. 3. Required, permitted, or forbidden x509 extensions in the request (including whether subjectAltNames are allowed, which types, restrictions on allowed values) and behavior when a disallowed extension is requested. 4. Required, permitted, or forbidden key usages / extended key usages. 5. Expiration/certificate lifetime: whether it is fixed by the signer, configurable by the admin. 6. Whether or not requests for CA certificates are allowed.
        :param expiration_seconds: expirationSeconds is the requested duration of validity of the issued certificate. The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration. The v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager. Certificate signers may not honor this field for various reasons: 1. Old signer that is unaware of the field (such as the in-tree implementations prior to v1.22) 2. Signer whose configured maximum is shorter than the requested duration 3. Signer whose configured minimum is longer than the requested duration The minimum valid value for expirationSeconds is 600, i.e. 10 minutes. As of v1.22, this field is beta and is controlled via the CSRDuration feature gate.
        :param extra: extra contains extra attributes of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.
        :param groups: groups contains group membership of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.
        :param uid: uid contains the uid of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.
        :param usages: usages specifies a set of key usages requested in the issued certificate. Requests for TLS client certificates typically request: "digital signature", "key encipherment", "client auth". Requests for TLS serving certificates typically request: "key encipherment", "digital signature", "server auth". Valid values are: "signing", "digital signature", "content commitment", "key encipherment", "key agreement", "data encipherment", "cert sign", "crl sign", "encipher only", "decipher only", "any", "server auth", "client auth", "code signing", "email protection", "s/mime", "ipsec end system", "ipsec tunnel", "ipsec user", "timestamping", "ocsp signing", "microsoft sgc", "netscape sgc"
        :param username: username contains the name of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec
        '''
        if __debug__:
            def stub(
                *,
                request: builtins.str,
                signer_name: builtins.str,
                expiration_seconds: typing.Optional[jsii.Number] = None,
                extra: typing.Optional[typing.Mapping[builtins.str, typing.Sequence[builtins.str]]] = None,
                groups: typing.Optional[typing.Sequence[builtins.str]] = None,
                uid: typing.Optional[builtins.str] = None,
                usages: typing.Optional[typing.Sequence[builtins.str]] = None,
                username: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument request", value=request, expected_type=type_hints["request"])
            check_type(argname="argument signer_name", value=signer_name, expected_type=type_hints["signer_name"])
            check_type(argname="argument expiration_seconds", value=expiration_seconds, expected_type=type_hints["expiration_seconds"])
            check_type(argname="argument extra", value=extra, expected_type=type_hints["extra"])
            check_type(argname="argument groups", value=groups, expected_type=type_hints["groups"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
            check_type(argname="argument usages", value=usages, expected_type=type_hints["usages"])
            check_type(argname="argument username", value=username, expected_type=type_hints["username"])
        self._values: typing.Dict[str, typing.Any] = {
            "request": request,
            "signer_name": signer_name,
        }
        if expiration_seconds is not None:
            self._values["expiration_seconds"] = expiration_seconds
        if extra is not None:
            self._values["extra"] = extra
        if groups is not None:
            self._values["groups"] = groups
        if uid is not None:
            self._values["uid"] = uid
        if usages is not None:
            self._values["usages"] = usages
        if username is not None:
            self._values["username"] = username

    @builtins.property
    def request(self) -> builtins.str:
        '''request contains an x509 certificate signing request encoded in a "CERTIFICATE REQUEST" PEM block.

        When serialized as JSON or YAML, the data is additionally base64-encoded.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#request
        '''
        result = self._values.get("request")
        assert result is not None, "Required property 'request' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def signer_name(self) -> builtins.str:
        '''signerName indicates the requested signer, and is a qualified name.

        List/watch requests for CertificateSigningRequests can filter on this field using a "spec.signerName=NAME" fieldSelector.

        Well-known Kubernetes signers are:

        1. "kubernetes.io/kube-apiserver-client": issues client certificates that can be used to authenticate to kube-apiserver.
           Requests for this signer are never auto-approved by kube-controller-manager, can be issued by the "csrsigning" controller in kube-controller-manager.
        2. "kubernetes.io/kube-apiserver-client-kubelet": issues client certificates that kubelets use to authenticate to kube-apiserver.
           Requests for this signer can be auto-approved by the "csrapproving" controller in kube-controller-manager, and can be issued by the "csrsigning" controller in kube-controller-manager.
        3. "kubernetes.io/kubelet-serving" issues serving certificates that kubelets use to serve TLS endpoints, which kube-apiserver can connect to securely.
           Requests for this signer are never auto-approved by kube-controller-manager, and can be issued by the "csrsigning" controller in kube-controller-manager.

        More details are available at https://k8s.io/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers

        Custom signerNames can also be specified. The signer defines:

        1. Trust distribution: how trust (CA bundles) are distributed.
        2. Permitted subjects: and behavior when a disallowed subject is requested.
        3. Required, permitted, or forbidden x509 extensions in the request (including whether subjectAltNames are allowed, which types, restrictions on allowed values) and behavior when a disallowed extension is requested.
        4. Required, permitted, or forbidden key usages / extended key usages.
        5. Expiration/certificate lifetime: whether it is fixed by the signer, configurable by the admin.
        6. Whether or not requests for CA certificates are allowed.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#signerName
        '''
        result = self._values.get("signer_name")
        assert result is not None, "Required property 'signer_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def expiration_seconds(self) -> typing.Optional[jsii.Number]:
        '''expirationSeconds is the requested duration of validity of the issued certificate.

        The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration.

        The v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager.

        Certificate signers may not honor this field for various reasons:

        1. Old signer that is unaware of the field (such as the in-tree
           implementations prior to v1.22)
        2. Signer whose configured maximum is shorter than the requested duration
        3. Signer whose configured minimum is longer than the requested duration

        The minimum valid value for expirationSeconds is 600, i.e. 10 minutes.

        As of v1.22, this field is beta and is controlled via the CSRDuration feature gate.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#expirationSeconds
        '''
        result = self._values.get("expiration_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def extra(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]]:
        '''extra contains extra attributes of the user that created the CertificateSigningRequest.

        Populated by the API server on creation and immutable.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#extra
        '''
        result = self._values.get("extra")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]], result)

    @builtins.property
    def groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''groups contains group membership of the user that created the CertificateSigningRequest.

        Populated by the API server on creation and immutable.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#groups
        '''
        result = self._values.get("groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''uid contains the uid of the user that created the CertificateSigningRequest.

        Populated by the API server on creation and immutable.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def usages(self) -> typing.Optional[typing.List[builtins.str]]:
        '''usages specifies a set of key usages requested in the issued certificate.

        Requests for TLS client certificates typically request: "digital signature", "key encipherment", "client auth".

        Requests for TLS serving certificates typically request: "key encipherment", "digital signature", "server auth".

        Valid values are:
        "signing", "digital signature", "content commitment",
        "key encipherment", "key agreement", "data encipherment",
        "cert sign", "crl sign", "encipher only", "decipher only", "any",
        "server auth", "client auth",
        "code signing", "email protection", "s/mime",
        "ipsec end system", "ipsec tunnel", "ipsec user",
        "timestamping", "ocsp signing", "microsoft sgc", "netscape sgc"

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#usages
        '''
        result = self._values.get("usages")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def username(self) -> typing.Optional[builtins.str]:
        '''username contains the name of the user that created the CertificateSigningRequest.

        Populated by the API server on creation and immutable.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestSpec#username
        '''
        result = self._values.get("username")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CertificateSigningRequestSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CinderPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "volume_id": "volumeId",
        "fs_type": "fsType",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
    },
)
class CinderPersistentVolumeSource:
    def __init__(
        self,
        *,
        volume_id: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents a cinder volume resource in Openstack.

        A Cinder volume must exist before mounting to a container. The volume must also be in the same region as the kubelet. Cinder volumes support ownership management and SELinux relabeling.

        :param volume_id: volume id used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param secret_ref: Optional: points to a secret object containing parameters used to connect to OpenStack.

        :schema: io.k8s.api.core.v1.CinderPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = SecretReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                volume_id: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument volume_id", value=volume_id, expected_type=type_hints["volume_id"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "volume_id": volume_id,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def volume_id(self) -> builtins.str:
        '''volume id used to identify the volume in cinder.

        More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.CinderPersistentVolumeSource#volumeID
        '''
        result = self._values.get("volume_id")
        assert result is not None, "Required property 'volume_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.CinderPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.CinderPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["SecretReference"]:
        '''Optional: points to a secret object containing parameters used to connect to OpenStack.

        :schema: io.k8s.api.core.v1.CinderPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CinderPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CinderVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "volume_id": "volumeId",
        "fs_type": "fsType",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
    },
)
class CinderVolumeSource:
    def __init__(
        self,
        *,
        volume_id: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents a cinder volume resource in Openstack.

        A Cinder volume must exist before mounting to a container. The volume must also be in the same region as the kubelet. Cinder volumes support ownership management and SELinux relabeling.

        :param volume_id: volume id used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param secret_ref: Optional: points to a secret object containing parameters used to connect to OpenStack.

        :schema: io.k8s.api.core.v1.CinderVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                volume_id: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument volume_id", value=volume_id, expected_type=type_hints["volume_id"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "volume_id": volume_id,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def volume_id(self) -> builtins.str:
        '''volume id used to identify the volume in cinder.

        More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.CinderVolumeSource#volumeID
        '''
        result = self._values.get("volume_id")
        assert result is not None, "Required property 'volume_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.CinderVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.CinderVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["LocalObjectReference"]:
        '''Optional: points to a secret object containing parameters used to connect to OpenStack.

        :schema: io.k8s.api.core.v1.CinderVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["LocalObjectReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CinderVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ClientIpConfig",
    jsii_struct_bases=[],
    name_mapping={"timeout_seconds": "timeoutSeconds"},
)
class ClientIpConfig:
    def __init__(self, *, timeout_seconds: typing.Optional[jsii.Number] = None) -> None:
        '''ClientIPConfig represents the configurations of Client IP based session affinity.

        :param timeout_seconds: timeoutSeconds specifies the seconds of ClientIP type session sticky time. The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". Default value is 10800(for 3 hours).

        :schema: io.k8s.api.core.v1.ClientIPConfig
        '''
        if __debug__:
            def stub(*, timeout_seconds: typing.Optional[jsii.Number] = None) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument timeout_seconds", value=timeout_seconds, expected_type=type_hints["timeout_seconds"])
        self._values: typing.Dict[str, typing.Any] = {}
        if timeout_seconds is not None:
            self._values["timeout_seconds"] = timeout_seconds

    @builtins.property
    def timeout_seconds(self) -> typing.Optional[jsii.Number]:
        '''timeoutSeconds specifies the seconds of ClientIP type session sticky time.

        The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". Default value is 10800(for 3 hours).

        :schema: io.k8s.api.core.v1.ClientIPConfig#timeoutSeconds
        '''
        result = self._values.get("timeout_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ClientIpConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ComponentCondition",
    jsii_struct_bases=[],
    name_mapping={
        "status": "status",
        "type": "type",
        "error": "error",
        "message": "message",
    },
)
class ComponentCondition:
    def __init__(
        self,
        *,
        status: builtins.str,
        type: builtins.str,
        error: typing.Optional[builtins.str] = None,
        message: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Information about the condition of a component.

        :param status: Status of the condition for a component. Valid values for "Healthy": "True", "False", or "Unknown".
        :param type: Type of condition for a component. Valid value: "Healthy"
        :param error: Condition error code for a component. For example, a health check error code.
        :param message: Message about the condition for a component. For example, information about a health check.

        :schema: io.k8s.api.core.v1.ComponentCondition
        '''
        if __debug__:
            def stub(
                *,
                status: builtins.str,
                type: builtins.str,
                error: typing.Optional[builtins.str] = None,
                message: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument status", value=status, expected_type=type_hints["status"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument error", value=error, expected_type=type_hints["error"])
            check_type(argname="argument message", value=message, expected_type=type_hints["message"])
        self._values: typing.Dict[str, typing.Any] = {
            "status": status,
            "type": type,
        }
        if error is not None:
            self._values["error"] = error
        if message is not None:
            self._values["message"] = message

    @builtins.property
    def status(self) -> builtins.str:
        '''Status of the condition for a component.

        Valid values for "Healthy": "True", "False", or "Unknown".

        :schema: io.k8s.api.core.v1.ComponentCondition#status
        '''
        result = self._values.get("status")
        assert result is not None, "Required property 'status' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def type(self) -> builtins.str:
        '''Type of condition for a component.

        Valid value: "Healthy"

        :schema: io.k8s.api.core.v1.ComponentCondition#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def error(self) -> typing.Optional[builtins.str]:
        '''Condition error code for a component.

        For example, a health check error code.

        :schema: io.k8s.api.core.v1.ComponentCondition#error
        '''
        result = self._values.get("error")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def message(self) -> typing.Optional[builtins.str]:
        '''Message about the condition for a component.

        For example, information about a health check.

        :schema: io.k8s.api.core.v1.ComponentCondition#message
        '''
        result = self._values.get("message")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ComponentCondition(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ConfigMapEnvSource",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "optional": "optional"},
)
class ConfigMapEnvSource:
    def __init__(
        self,
        *,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''ConfigMapEnvSource selects a ConfigMap to populate the environment variables with.

        The contents of the target ConfigMap's Data field will represent the key-value pairs as environment variables.

        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the ConfigMap must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapEnvSource
        '''
        if __debug__:
            def stub(
                *,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {}
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.ConfigMapEnvSource#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the ConfigMap must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapEnvSource#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigMapEnvSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ConfigMapKeySelector",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "name": "name", "optional": "optional"},
)
class ConfigMapKeySelector:
    def __init__(
        self,
        *,
        key: builtins.str,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Selects a key from a ConfigMap.

        :param key: The key to select.
        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the ConfigMap or its key must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapKeySelector
        '''
        if __debug__:
            def stub(
                *,
                key: builtins.str,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {
            "key": key,
        }
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def key(self) -> builtins.str:
        '''The key to select.

        :schema: io.k8s.api.core.v1.ConfigMapKeySelector#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.ConfigMapKeySelector#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the ConfigMap or its key must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapKeySelector#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigMapKeySelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ConfigMapNodeConfigSource",
    jsii_struct_bases=[],
    name_mapping={
        "kubelet_config_key": "kubeletConfigKey",
        "name": "name",
        "namespace": "namespace",
        "resource_version": "resourceVersion",
        "uid": "uid",
    },
)
class ConfigMapNodeConfigSource:
    def __init__(
        self,
        *,
        kubelet_config_key: builtins.str,
        name: builtins.str,
        namespace: builtins.str,
        resource_version: typing.Optional[builtins.str] = None,
        uid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ConfigMapNodeConfigSource contains the information to reference a ConfigMap as a config source for the Node.

        This API is deprecated since 1.22: https://git.k8s.io/enhancements/keps/sig-node/281-dynamic-kubelet-configuration

        :param kubelet_config_key: KubeletConfigKey declares which key of the referenced ConfigMap corresponds to the KubeletConfiguration structure This field is required in all cases.
        :param name: Name is the metadata.name of the referenced ConfigMap. This field is required in all cases.
        :param namespace: Namespace is the metadata.namespace of the referenced ConfigMap. This field is required in all cases.
        :param resource_version: ResourceVersion is the metadata.ResourceVersion of the referenced ConfigMap. This field is forbidden in Node.Spec, and required in Node.Status.
        :param uid: UID is the metadata.UID of the referenced ConfigMap. This field is forbidden in Node.Spec, and required in Node.Status.

        :schema: io.k8s.api.core.v1.ConfigMapNodeConfigSource
        '''
        if __debug__:
            def stub(
                *,
                kubelet_config_key: builtins.str,
                name: builtins.str,
                namespace: builtins.str,
                resource_version: typing.Optional[builtins.str] = None,
                uid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kubelet_config_key", value=kubelet_config_key, expected_type=type_hints["kubelet_config_key"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
            check_type(argname="argument resource_version", value=resource_version, expected_type=type_hints["resource_version"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
        self._values: typing.Dict[str, typing.Any] = {
            "kubelet_config_key": kubelet_config_key,
            "name": name,
            "namespace": namespace,
        }
        if resource_version is not None:
            self._values["resource_version"] = resource_version
        if uid is not None:
            self._values["uid"] = uid

    @builtins.property
    def kubelet_config_key(self) -> builtins.str:
        '''KubeletConfigKey declares which key of the referenced ConfigMap corresponds to the KubeletConfiguration structure This field is required in all cases.

        :schema: io.k8s.api.core.v1.ConfigMapNodeConfigSource#kubeletConfigKey
        '''
        result = self._values.get("kubelet_config_key")
        assert result is not None, "Required property 'kubelet_config_key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the metadata.name of the referenced ConfigMap. This field is required in all cases.

        :schema: io.k8s.api.core.v1.ConfigMapNodeConfigSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def namespace(self) -> builtins.str:
        '''Namespace is the metadata.namespace of the referenced ConfigMap. This field is required in all cases.

        :schema: io.k8s.api.core.v1.ConfigMapNodeConfigSource#namespace
        '''
        result = self._values.get("namespace")
        assert result is not None, "Required property 'namespace' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def resource_version(self) -> typing.Optional[builtins.str]:
        '''ResourceVersion is the metadata.ResourceVersion of the referenced ConfigMap. This field is forbidden in Node.Spec, and required in Node.Status.

        :schema: io.k8s.api.core.v1.ConfigMapNodeConfigSource#resourceVersion
        '''
        result = self._values.get("resource_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''UID is the metadata.UID of the referenced ConfigMap. This field is forbidden in Node.Spec, and required in Node.Status.

        :schema: io.k8s.api.core.v1.ConfigMapNodeConfigSource#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigMapNodeConfigSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ConfigMapProjection",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "name": "name", "optional": "optional"},
)
class ConfigMapProjection:
    def __init__(
        self,
        *,
        items: typing.Optional[typing.Sequence[typing.Union["KeyToPath", typing.Dict[str, typing.Any]]]] = None,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Adapts a ConfigMap into a projected volume.

        The contents of the target ConfigMap's Data field will be presented in a projected volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. Note that this is identical to a configmap volume source without the default mode.

        :param items: If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.
        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the ConfigMap or its keys must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapProjection
        '''
        if __debug__:
            def stub(
                *,
                items: typing.Optional[typing.Sequence[typing.Union[KeyToPath, typing.Dict[str, typing.Any]]]] = None,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {}
        if items is not None:
            self._values["items"] = items
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def items(self) -> typing.Optional[typing.List["KeyToPath"]]:
        '''If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value.

        If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.

        :schema: io.k8s.api.core.v1.ConfigMapProjection#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Optional[typing.List["KeyToPath"]], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.ConfigMapProjection#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the ConfigMap or its keys must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapProjection#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigMapProjection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ConfigMapVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "default_mode": "defaultMode",
        "items": "items",
        "name": "name",
        "optional": "optional",
    },
)
class ConfigMapVolumeSource:
    def __init__(
        self,
        *,
        default_mode: typing.Optional[jsii.Number] = None,
        items: typing.Optional[typing.Sequence[typing.Union["KeyToPath", typing.Dict[str, typing.Any]]]] = None,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Adapts a ConfigMap into a volume.

        The contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.

        :param default_mode: Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. Default: 644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.
        :param items: If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.
        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the ConfigMap or its keys must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                default_mode: typing.Optional[jsii.Number] = None,
                items: typing.Optional[typing.Sequence[typing.Union[KeyToPath, typing.Dict[str, typing.Any]]]] = None,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument default_mode", value=default_mode, expected_type=type_hints["default_mode"])
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {}
        if default_mode is not None:
            self._values["default_mode"] = default_mode
        if items is not None:
            self._values["items"] = items
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def default_mode(self) -> typing.Optional[jsii.Number]:
        '''Optional: mode bits used to set permissions on created files by default.

        Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :default: 644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.ConfigMapVolumeSource#defaultMode
        '''
        result = self._values.get("default_mode")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def items(self) -> typing.Optional[typing.List["KeyToPath"]]:
        '''If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value.

        If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.

        :schema: io.k8s.api.core.v1.ConfigMapVolumeSource#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Optional[typing.List["KeyToPath"]], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.ConfigMapVolumeSource#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the ConfigMap or its keys must be defined.

        :schema: io.k8s.api.core.v1.ConfigMapVolumeSource#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigMapVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Container",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "args": "args",
        "command": "command",
        "env": "env",
        "env_from": "envFrom",
        "image": "image",
        "image_pull_policy": "imagePullPolicy",
        "lifecycle": "lifecycle",
        "liveness_probe": "livenessProbe",
        "ports": "ports",
        "readiness_probe": "readinessProbe",
        "resources": "resources",
        "security_context": "securityContext",
        "startup_probe": "startupProbe",
        "stdin": "stdin",
        "stdin_once": "stdinOnce",
        "termination_message_path": "terminationMessagePath",
        "termination_message_policy": "terminationMessagePolicy",
        "tty": "tty",
        "volume_devices": "volumeDevices",
        "volume_mounts": "volumeMounts",
        "working_dir": "workingDir",
    },
)
class Container:
    def __init__(
        self,
        *,
        name: builtins.str,
        args: typing.Optional[typing.Sequence[builtins.str]] = None,
        command: typing.Optional[typing.Sequence[builtins.str]] = None,
        env: typing.Optional[typing.Sequence[typing.Union["EnvVar", typing.Dict[str, typing.Any]]]] = None,
        env_from: typing.Optional[typing.Sequence[typing.Union["EnvFromSource", typing.Dict[str, typing.Any]]]] = None,
        image: typing.Optional[builtins.str] = None,
        image_pull_policy: typing.Optional["IoK8SApiCoreV1ContainerImagePullPolicy"] = None,
        lifecycle: typing.Optional[typing.Union["Lifecycle", typing.Dict[str, typing.Any]]] = None,
        liveness_probe: typing.Optional[typing.Union["Probe", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union["ContainerPort", typing.Dict[str, typing.Any]]]] = None,
        readiness_probe: typing.Optional[typing.Union["Probe", typing.Dict[str, typing.Any]]] = None,
        resources: typing.Optional[typing.Union["ResourceRequirements", typing.Dict[str, typing.Any]]] = None,
        security_context: typing.Optional[typing.Union["SecurityContext", typing.Dict[str, typing.Any]]] = None,
        startup_probe: typing.Optional[typing.Union["Probe", typing.Dict[str, typing.Any]]] = None,
        stdin: typing.Optional[builtins.bool] = None,
        stdin_once: typing.Optional[builtins.bool] = None,
        termination_message_path: typing.Optional[builtins.str] = None,
        termination_message_policy: typing.Optional["IoK8SApiCoreV1ContainerTerminationMessagePolicy"] = None,
        tty: typing.Optional[builtins.bool] = None,
        volume_devices: typing.Optional[typing.Sequence[typing.Union["VolumeDevice", typing.Dict[str, typing.Any]]]] = None,
        volume_mounts: typing.Optional[typing.Sequence[typing.Union["VolumeMount", typing.Dict[str, typing.Any]]]] = None,
        working_dir: typing.Optional[builtins.str] = None,
    ) -> None:
        '''A single application container that you want to run within a pod.

        :param name: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.
        :param args: Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
        :param command: Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
        :param env: List of environment variables to set in the container. Cannot be updated.
        :param env_from: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.
        :param image: Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.
        :param image_pull_policy: Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images Possible enum values: - ``"Always"`` means that kubelet always attempts to pull the latest image. Container will fail If the pull fails. - ``"IfNotPresent"`` means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails. - ``"Never"`` means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present Default: Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
        :param lifecycle: Actions that the management system should take in response to container lifecycle events. Cannot be updated.
        :param liveness_probe: Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
        :param ports: List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated.
        :param readiness_probe: Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
        :param resources: Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        :param security_context: SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
        :param startup_probe: StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
        :param stdin: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. Default: false.
        :param stdin_once: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false Default: false
        :param termination_message_path: Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated. Default: dev/termination-log. Cannot be updated.
        :param termination_message_policy: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. Possible enum values: - ``"FallbackToLogsOnError"`` will read the most recent contents of the container logs for the container status message when the container exits with an error and the terminationMessagePath has no contents. - ``"File"`` is the default behavior and will set the container status message to the contents of the container's terminationMessagePath when the container exits. Default: File. Cannot be updated.
        :param tty: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. Default: false.
        :param volume_devices: volumeDevices is the list of block devices to be used by the container.
        :param volume_mounts: Pod volumes to mount into the container's filesystem. Cannot be updated.
        :param working_dir: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.

        :schema: io.k8s.api.core.v1.Container
        '''
        if isinstance(lifecycle, dict):
            lifecycle = Lifecycle(**lifecycle)
        if isinstance(liveness_probe, dict):
            liveness_probe = Probe(**liveness_probe)
        if isinstance(readiness_probe, dict):
            readiness_probe = Probe(**readiness_probe)
        if isinstance(resources, dict):
            resources = ResourceRequirements(**resources)
        if isinstance(security_context, dict):
            security_context = SecurityContext(**security_context)
        if isinstance(startup_probe, dict):
            startup_probe = Probe(**startup_probe)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                args: typing.Optional[typing.Sequence[builtins.str]] = None,
                command: typing.Optional[typing.Sequence[builtins.str]] = None,
                env: typing.Optional[typing.Sequence[typing.Union[EnvVar, typing.Dict[str, typing.Any]]]] = None,
                env_from: typing.Optional[typing.Sequence[typing.Union[EnvFromSource, typing.Dict[str, typing.Any]]]] = None,
                image: typing.Optional[builtins.str] = None,
                image_pull_policy: typing.Optional[IoK8SApiCoreV1ContainerImagePullPolicy] = None,
                lifecycle: typing.Optional[typing.Union[Lifecycle, typing.Dict[str, typing.Any]]] = None,
                liveness_probe: typing.Optional[typing.Union[Probe, typing.Dict[str, typing.Any]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[ContainerPort, typing.Dict[str, typing.Any]]]] = None,
                readiness_probe: typing.Optional[typing.Union[Probe, typing.Dict[str, typing.Any]]] = None,
                resources: typing.Optional[typing.Union[ResourceRequirements, typing.Dict[str, typing.Any]]] = None,
                security_context: typing.Optional[typing.Union[SecurityContext, typing.Dict[str, typing.Any]]] = None,
                startup_probe: typing.Optional[typing.Union[Probe, typing.Dict[str, typing.Any]]] = None,
                stdin: typing.Optional[builtins.bool] = None,
                stdin_once: typing.Optional[builtins.bool] = None,
                termination_message_path: typing.Optional[builtins.str] = None,
                termination_message_policy: typing.Optional[IoK8SApiCoreV1ContainerTerminationMessagePolicy] = None,
                tty: typing.Optional[builtins.bool] = None,
                volume_devices: typing.Optional[typing.Sequence[typing.Union[VolumeDevice, typing.Dict[str, typing.Any]]]] = None,
                volume_mounts: typing.Optional[typing.Sequence[typing.Union[VolumeMount, typing.Dict[str, typing.Any]]]] = None,
                working_dir: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument args", value=args, expected_type=type_hints["args"])
            check_type(argname="argument command", value=command, expected_type=type_hints["command"])
            check_type(argname="argument env", value=env, expected_type=type_hints["env"])
            check_type(argname="argument env_from", value=env_from, expected_type=type_hints["env_from"])
            check_type(argname="argument image", value=image, expected_type=type_hints["image"])
            check_type(argname="argument image_pull_policy", value=image_pull_policy, expected_type=type_hints["image_pull_policy"])
            check_type(argname="argument lifecycle", value=lifecycle, expected_type=type_hints["lifecycle"])
            check_type(argname="argument liveness_probe", value=liveness_probe, expected_type=type_hints["liveness_probe"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
            check_type(argname="argument readiness_probe", value=readiness_probe, expected_type=type_hints["readiness_probe"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
            check_type(argname="argument security_context", value=security_context, expected_type=type_hints["security_context"])
            check_type(argname="argument startup_probe", value=startup_probe, expected_type=type_hints["startup_probe"])
            check_type(argname="argument stdin", value=stdin, expected_type=type_hints["stdin"])
            check_type(argname="argument stdin_once", value=stdin_once, expected_type=type_hints["stdin_once"])
            check_type(argname="argument termination_message_path", value=termination_message_path, expected_type=type_hints["termination_message_path"])
            check_type(argname="argument termination_message_policy", value=termination_message_policy, expected_type=type_hints["termination_message_policy"])
            check_type(argname="argument tty", value=tty, expected_type=type_hints["tty"])
            check_type(argname="argument volume_devices", value=volume_devices, expected_type=type_hints["volume_devices"])
            check_type(argname="argument volume_mounts", value=volume_mounts, expected_type=type_hints["volume_mounts"])
            check_type(argname="argument working_dir", value=working_dir, expected_type=type_hints["working_dir"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if args is not None:
            self._values["args"] = args
        if command is not None:
            self._values["command"] = command
        if env is not None:
            self._values["env"] = env
        if env_from is not None:
            self._values["env_from"] = env_from
        if image is not None:
            self._values["image"] = image
        if image_pull_policy is not None:
            self._values["image_pull_policy"] = image_pull_policy
        if lifecycle is not None:
            self._values["lifecycle"] = lifecycle
        if liveness_probe is not None:
            self._values["liveness_probe"] = liveness_probe
        if ports is not None:
            self._values["ports"] = ports
        if readiness_probe is not None:
            self._values["readiness_probe"] = readiness_probe
        if resources is not None:
            self._values["resources"] = resources
        if security_context is not None:
            self._values["security_context"] = security_context
        if startup_probe is not None:
            self._values["startup_probe"] = startup_probe
        if stdin is not None:
            self._values["stdin"] = stdin
        if stdin_once is not None:
            self._values["stdin_once"] = stdin_once
        if termination_message_path is not None:
            self._values["termination_message_path"] = termination_message_path
        if termination_message_policy is not None:
            self._values["termination_message_policy"] = termination_message_policy
        if tty is not None:
            self._values["tty"] = tty
        if volume_devices is not None:
            self._values["volume_devices"] = volume_devices
        if volume_mounts is not None:
            self._values["volume_mounts"] = volume_mounts
        if working_dir is not None:
            self._values["working_dir"] = working_dir

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the container specified as a DNS_LABEL.

        Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def args(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Arguments to the entrypoint.

        The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

        :schema: io.k8s.api.core.v1.Container#args
        '''
        result = self._values.get("args")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def command(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Entrypoint array.

        Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

        :schema: io.k8s.api.core.v1.Container#command
        '''
        result = self._values.get("command")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def env(self) -> typing.Optional[typing.List["EnvVar"]]:
        '''List of environment variables to set in the container.

        Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#env
        '''
        result = self._values.get("env")
        return typing.cast(typing.Optional[typing.List["EnvVar"]], result)

    @builtins.property
    def env_from(self) -> typing.Optional[typing.List["EnvFromSource"]]:
        '''List of sources to populate environment variables in the container.

        The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#envFrom
        '''
        result = self._values.get("env_from")
        return typing.cast(typing.Optional[typing.List["EnvFromSource"]], result)

    @builtins.property
    def image(self) -> typing.Optional[builtins.str]:
        '''Docker image name.

        More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.

        :schema: io.k8s.api.core.v1.Container#image
        '''
        result = self._values.get("image")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def image_pull_policy(
        self,
    ) -> typing.Optional["IoK8SApiCoreV1ContainerImagePullPolicy"]:
        '''Image pull policy.

        One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

        Possible enum values:

        - ``"Always"`` means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
        - ``"IfNotPresent"`` means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails.
        - ``"Never"`` means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present

        :default: Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

        :schema: io.k8s.api.core.v1.Container#imagePullPolicy
        '''
        result = self._values.get("image_pull_policy")
        return typing.cast(typing.Optional["IoK8SApiCoreV1ContainerImagePullPolicy"], result)

    @builtins.property
    def lifecycle(self) -> typing.Optional["Lifecycle"]:
        '''Actions that the management system should take in response to container lifecycle events.

        Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#lifecycle
        '''
        result = self._values.get("lifecycle")
        return typing.cast(typing.Optional["Lifecycle"], result)

    @builtins.property
    def liveness_probe(self) -> typing.Optional["Probe"]:
        '''Periodic probe of container liveness.

        Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :schema: io.k8s.api.core.v1.Container#livenessProbe
        '''
        result = self._values.get("liveness_probe")
        return typing.cast(typing.Optional["Probe"], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List["ContainerPort"]]:
        '''List of ports to expose from the container.

        Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List["ContainerPort"]], result)

    @builtins.property
    def readiness_probe(self) -> typing.Optional["Probe"]:
        '''Periodic probe of container service readiness.

        Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :schema: io.k8s.api.core.v1.Container#readinessProbe
        '''
        result = self._values.get("readiness_probe")
        return typing.cast(typing.Optional["Probe"], result)

    @builtins.property
    def resources(self) -> typing.Optional["ResourceRequirements"]:
        '''Compute Resources required by this container.

        Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

        :schema: io.k8s.api.core.v1.Container#resources
        '''
        result = self._values.get("resources")
        return typing.cast(typing.Optional["ResourceRequirements"], result)

    @builtins.property
    def security_context(self) -> typing.Optional["SecurityContext"]:
        '''SecurityContext defines the security options the container should be run with.

        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

        :schema: io.k8s.api.core.v1.Container#securityContext
        '''
        result = self._values.get("security_context")
        return typing.cast(typing.Optional["SecurityContext"], result)

    @builtins.property
    def startup_probe(self) -> typing.Optional["Probe"]:
        '''StartupProbe indicates that the Pod has successfully initialized.

        If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :schema: io.k8s.api.core.v1.Container#startupProbe
        '''
        result = self._values.get("startup_probe")
        return typing.cast(typing.Optional["Probe"], result)

    @builtins.property
    def stdin(self) -> typing.Optional[builtins.bool]:
        '''Whether this container should allocate a buffer for stdin in the container runtime.

        If this is not set, reads from stdin in the container will always result in EOF. Default is false.

        :default: false.

        :schema: io.k8s.api.core.v1.Container#stdin
        '''
        result = self._values.get("stdin")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def stdin_once(self) -> typing.Optional[builtins.bool]:
        '''Whether the container runtime should close the stdin channel after it has been opened by a single attach.

        When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false

        :default: false

        :schema: io.k8s.api.core.v1.Container#stdinOnce
        '''
        result = self._values.get("stdin_once")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def termination_message_path(self) -> typing.Optional[builtins.str]:
        '''Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem.

        Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

        :default: dev/termination-log. Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#terminationMessagePath
        '''
        result = self._values.get("termination_message_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def termination_message_policy(
        self,
    ) -> typing.Optional["IoK8SApiCoreV1ContainerTerminationMessagePolicy"]:
        '''Indicate how the termination message should be populated.

        File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

        Possible enum values:

        - ``"FallbackToLogsOnError"`` will read the most recent contents of the container logs for the container status message when the container exits with an error and the terminationMessagePath has no contents.
        - ``"File"`` is the default behavior and will set the container status message to the contents of the container's terminationMessagePath when the container exits.

        :default: File. Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#terminationMessagePolicy
        '''
        result = self._values.get("termination_message_policy")
        return typing.cast(typing.Optional["IoK8SApiCoreV1ContainerTerminationMessagePolicy"], result)

    @builtins.property
    def tty(self) -> typing.Optional[builtins.bool]:
        '''Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.

        Default is false.

        :default: false.

        :schema: io.k8s.api.core.v1.Container#tty
        '''
        result = self._values.get("tty")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def volume_devices(self) -> typing.Optional[typing.List["VolumeDevice"]]:
        '''volumeDevices is the list of block devices to be used by the container.

        :schema: io.k8s.api.core.v1.Container#volumeDevices
        '''
        result = self._values.get("volume_devices")
        return typing.cast(typing.Optional[typing.List["VolumeDevice"]], result)

    @builtins.property
    def volume_mounts(self) -> typing.Optional[typing.List["VolumeMount"]]:
        '''Pod volumes to mount into the container's filesystem.

        Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#volumeMounts
        '''
        result = self._values.get("volume_mounts")
        return typing.cast(typing.Optional[typing.List["VolumeMount"]], result)

    @builtins.property
    def working_dir(self) -> typing.Optional[builtins.str]:
        '''Container's working directory.

        If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.

        :schema: io.k8s.api.core.v1.Container#workingDir
        '''
        result = self._values.get("working_dir")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Container(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ContainerPort",
    jsii_struct_bases=[],
    name_mapping={
        "container_port": "containerPort",
        "host_ip": "hostIp",
        "host_port": "hostPort",
        "name": "name",
        "protocol": "protocol",
    },
)
class ContainerPort:
    def __init__(
        self,
        *,
        container_port: jsii.Number,
        host_ip: typing.Optional[builtins.str] = None,
        host_port: typing.Optional[jsii.Number] = None,
        name: typing.Optional[builtins.str] = None,
        protocol: typing.Optional["IoK8SApiCoreV1ContainerPortProtocol"] = None,
    ) -> None:
        '''ContainerPort represents a network port in a single container.

        :param container_port: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536.
        :param host_ip: What host IP to bind the external port to.
        :param host_port: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this.
        :param name: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services.
        :param protocol: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". Possible enum values: - ``"SCTP"`` is the SCTP protocol. - ``"TCP"`` is the TCP protocol. - ``"UDP"`` is the UDP protocol. Default: TCP".

        :schema: io.k8s.api.core.v1.ContainerPort
        '''
        if __debug__:
            def stub(
                *,
                container_port: jsii.Number,
                host_ip: typing.Optional[builtins.str] = None,
                host_port: typing.Optional[jsii.Number] = None,
                name: typing.Optional[builtins.str] = None,
                protocol: typing.Optional[IoK8SApiCoreV1ContainerPortProtocol] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument container_port", value=container_port, expected_type=type_hints["container_port"])
            check_type(argname="argument host_ip", value=host_ip, expected_type=type_hints["host_ip"])
            check_type(argname="argument host_port", value=host_port, expected_type=type_hints["host_port"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
        self._values: typing.Dict[str, typing.Any] = {
            "container_port": container_port,
        }
        if host_ip is not None:
            self._values["host_ip"] = host_ip
        if host_port is not None:
            self._values["host_port"] = host_port
        if name is not None:
            self._values["name"] = name
        if protocol is not None:
            self._values["protocol"] = protocol

    @builtins.property
    def container_port(self) -> jsii.Number:
        '''Number of port to expose on the pod's IP address.

        This must be a valid port number, 0 < x < 65536.

        :schema: io.k8s.api.core.v1.ContainerPort#containerPort
        '''
        result = self._values.get("container_port")
        assert result is not None, "Required property 'container_port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def host_ip(self) -> typing.Optional[builtins.str]:
        '''What host IP to bind the external port to.

        :schema: io.k8s.api.core.v1.ContainerPort#hostIP
        '''
        result = self._values.get("host_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def host_port(self) -> typing.Optional[jsii.Number]:
        '''Number of port to expose on the host.

        If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this.

        :schema: io.k8s.api.core.v1.ContainerPort#hostPort
        '''
        result = self._values.get("host_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''If specified, this must be an IANA_SVC_NAME and unique within the pod.

        Each named port in a pod must have a unique name. Name for the port that can be referred to by services.

        :schema: io.k8s.api.core.v1.ContainerPort#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def protocol(self) -> typing.Optional["IoK8SApiCoreV1ContainerPortProtocol"]:
        '''Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".

        Possible enum values:

        - ``"SCTP"`` is the SCTP protocol.
        - ``"TCP"`` is the TCP protocol.
        - ``"UDP"`` is the UDP protocol.

        :default: TCP".

        :schema: io.k8s.api.core.v1.ContainerPort#protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional["IoK8SApiCoreV1ContainerPortProtocol"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ContainerPort(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ContainerResourceMetricSourceV2",
    jsii_struct_bases=[],
    name_mapping={"container": "container", "name": "name", "target": "target"},
)
class ContainerResourceMetricSourceV2:
    def __init__(
        self,
        *,
        container: builtins.str,
        name: builtins.str,
        target: typing.Union["MetricTargetV2", typing.Dict[str, typing.Any]],
    ) -> None:
        '''ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory).  The values will be averaged together before being compared to the target.  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.  Only one "target" type should be set.

        :param container: container is the name of the container in the pods of the scaling target.
        :param name: name is the name of the resource in question.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ContainerResourceMetricSource
        '''
        if isinstance(target, dict):
            target = MetricTargetV2(**target)
        if __debug__:
            def stub(
                *,
                container: builtins.str,
                name: builtins.str,
                target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument container", value=container, expected_type=type_hints["container"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "container": container,
            "name": name,
            "target": target,
        }

    @builtins.property
    def container(self) -> builtins.str:
        '''container is the name of the container in the pods of the scaling target.

        :schema: io.k8s.api.autoscaling.v2.ContainerResourceMetricSource#container
        '''
        result = self._values.get("container")
        assert result is not None, "Required property 'container' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the resource in question.

        :schema: io.k8s.api.autoscaling.v2.ContainerResourceMetricSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target(self) -> "MetricTargetV2":
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ContainerResourceMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast("MetricTargetV2", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ContainerResourceMetricSourceV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ContainerResourceMetricSourceV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "container": "container",
        "name": "name",
        "target_average_utilization": "targetAverageUtilization",
        "target_average_value": "targetAverageValue",
    },
)
class ContainerResourceMetricSourceV2Beta1:
    def __init__(
        self,
        *,
        container: builtins.str,
        name: builtins.str,
        target_average_utilization: typing.Optional[jsii.Number] = None,
        target_average_value: typing.Optional["Quantity"] = None,
    ) -> None:
        '''ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory).  The values will be averaged together before being compared to the target.  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.  Only one "target" type should be set.

        :param container: container is the name of the container in the pods of the scaling target.
        :param name: name is the name of the resource in question.
        :param target_average_utilization: targetAverageUtilization 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.
        :param target_average_value: targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the "pods" metric source type.

        :schema: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource
        '''
        if __debug__:
            def stub(
                *,
                container: builtins.str,
                name: builtins.str,
                target_average_utilization: typing.Optional[jsii.Number] = None,
                target_average_value: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument container", value=container, expected_type=type_hints["container"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument target_average_utilization", value=target_average_utilization, expected_type=type_hints["target_average_utilization"])
            check_type(argname="argument target_average_value", value=target_average_value, expected_type=type_hints["target_average_value"])
        self._values: typing.Dict[str, typing.Any] = {
            "container": container,
            "name": name,
        }
        if target_average_utilization is not None:
            self._values["target_average_utilization"] = target_average_utilization
        if target_average_value is not None:
            self._values["target_average_value"] = target_average_value

    @builtins.property
    def container(self) -> builtins.str:
        '''container is the name of the container in the pods of the scaling target.

        :schema: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource#container
        '''
        result = self._values.get("container")
        assert result is not None, "Required property 'container' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the resource in question.

        :schema: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target_average_utilization(self) -> typing.Optional[jsii.Number]:
        '''targetAverageUtilization 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.

        :schema: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource#targetAverageUtilization
        '''
        result = self._values.get("target_average_utilization")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def target_average_value(self) -> typing.Optional["Quantity"]:
        '''targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the "pods" metric source type.

        :schema: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource#targetAverageValue
        '''
        result = self._values.get("target_average_value")
        return typing.cast(typing.Optional["Quantity"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ContainerResourceMetricSourceV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ContainerResourceMetricSourceV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"container": "container", "name": "name", "target": "target"},
)
class ContainerResourceMetricSourceV2Beta2:
    def __init__(
        self,
        *,
        container: builtins.str,
        name: builtins.str,
        target: typing.Union["MetricTargetV2Beta2", typing.Dict[str, typing.Any]],
    ) -> None:
        '''ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory).  The values will be averaged together before being compared to the target.  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.  Only one "target" type should be set.

        :param container: container is the name of the container in the pods of the scaling target.
        :param name: name is the name of the resource in question.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource
        '''
        if isinstance(target, dict):
            target = MetricTargetV2Beta2(**target)
        if __debug__:
            def stub(
                *,
                container: builtins.str,
                name: builtins.str,
                target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument container", value=container, expected_type=type_hints["container"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "container": container,
            "name": name,
            "target": target,
        }

    @builtins.property
    def container(self) -> builtins.str:
        '''container is the name of the container in the pods of the scaling target.

        :schema: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource#container
        '''
        result = self._values.get("container")
        assert result is not None, "Required property 'container' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the resource in question.

        :schema: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target(self) -> "MetricTargetV2Beta2":
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast("MetricTargetV2Beta2", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ContainerResourceMetricSourceV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CronJobSpec",
    jsii_struct_bases=[],
    name_mapping={
        "job_template": "jobTemplate",
        "schedule": "schedule",
        "concurrency_policy": "concurrencyPolicy",
        "failed_jobs_history_limit": "failedJobsHistoryLimit",
        "starting_deadline_seconds": "startingDeadlineSeconds",
        "successful_jobs_history_limit": "successfulJobsHistoryLimit",
        "suspend": "suspend",
    },
)
class CronJobSpec:
    def __init__(
        self,
        *,
        job_template: typing.Union["JobTemplateSpec", typing.Dict[str, typing.Any]],
        schedule: builtins.str,
        concurrency_policy: typing.Optional["IoK8SApiBatchV1CronJobSpecConcurrencyPolicy"] = None,
        failed_jobs_history_limit: typing.Optional[jsii.Number] = None,
        starting_deadline_seconds: typing.Optional[jsii.Number] = None,
        successful_jobs_history_limit: typing.Optional[jsii.Number] = None,
        suspend: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''CronJobSpec describes how the job execution will look like and when it will actually run.

        :param job_template: Specifies the job that will be created when executing a CronJob.
        :param schedule: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
        :param concurrency_policy: Specifies how to treat concurrent executions of a Job. Valid values are: - "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - "Replace": cancels currently running job and replaces it with a new one Possible enum values: - ``"Allow"`` allows CronJobs to run concurrently. - ``"Forbid"`` forbids concurrent runs, skipping next run if previous hasn't finished yet. - ``"Replace"`` cancels currently running job and replaces it with a new one.
        :param failed_jobs_history_limit: The number of failed finished jobs to retain. Value must be non-negative integer. Defaults to 1. Default: 1.
        :param starting_deadline_seconds: Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Missed jobs executions will be counted as failed ones.
        :param successful_jobs_history_limit: The number of successful finished jobs to retain. Value must be non-negative integer. Defaults to 3. Default: 3.
        :param suspend: This flag tells the controller to suspend subsequent executions, it does not apply to already started executions. Defaults to false. Default: false.

        :schema: io.k8s.api.batch.v1.CronJobSpec
        '''
        if isinstance(job_template, dict):
            job_template = JobTemplateSpec(**job_template)
        if __debug__:
            def stub(
                *,
                job_template: typing.Union[JobTemplateSpec, typing.Dict[str, typing.Any]],
                schedule: builtins.str,
                concurrency_policy: typing.Optional[IoK8SApiBatchV1CronJobSpecConcurrencyPolicy] = None,
                failed_jobs_history_limit: typing.Optional[jsii.Number] = None,
                starting_deadline_seconds: typing.Optional[jsii.Number] = None,
                successful_jobs_history_limit: typing.Optional[jsii.Number] = None,
                suspend: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument job_template", value=job_template, expected_type=type_hints["job_template"])
            check_type(argname="argument schedule", value=schedule, expected_type=type_hints["schedule"])
            check_type(argname="argument concurrency_policy", value=concurrency_policy, expected_type=type_hints["concurrency_policy"])
            check_type(argname="argument failed_jobs_history_limit", value=failed_jobs_history_limit, expected_type=type_hints["failed_jobs_history_limit"])
            check_type(argname="argument starting_deadline_seconds", value=starting_deadline_seconds, expected_type=type_hints["starting_deadline_seconds"])
            check_type(argname="argument successful_jobs_history_limit", value=successful_jobs_history_limit, expected_type=type_hints["successful_jobs_history_limit"])
            check_type(argname="argument suspend", value=suspend, expected_type=type_hints["suspend"])
        self._values: typing.Dict[str, typing.Any] = {
            "job_template": job_template,
            "schedule": schedule,
        }
        if concurrency_policy is not None:
            self._values["concurrency_policy"] = concurrency_policy
        if failed_jobs_history_limit is not None:
            self._values["failed_jobs_history_limit"] = failed_jobs_history_limit
        if starting_deadline_seconds is not None:
            self._values["starting_deadline_seconds"] = starting_deadline_seconds
        if successful_jobs_history_limit is not None:
            self._values["successful_jobs_history_limit"] = successful_jobs_history_limit
        if suspend is not None:
            self._values["suspend"] = suspend

    @builtins.property
    def job_template(self) -> "JobTemplateSpec":
        '''Specifies the job that will be created when executing a CronJob.

        :schema: io.k8s.api.batch.v1.CronJobSpec#jobTemplate
        '''
        result = self._values.get("job_template")
        assert result is not None, "Required property 'job_template' is missing"
        return typing.cast("JobTemplateSpec", result)

    @builtins.property
    def schedule(self) -> builtins.str:
        '''The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.

        :schema: io.k8s.api.batch.v1.CronJobSpec#schedule
        '''
        result = self._values.get("schedule")
        assert result is not None, "Required property 'schedule' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def concurrency_policy(
        self,
    ) -> typing.Optional["IoK8SApiBatchV1CronJobSpecConcurrencyPolicy"]:
        '''Specifies how to treat concurrent executions of a Job.

        Valid values are: - "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - "Replace": cancels currently running job and replaces it with a new one

        Possible enum values:

        - ``"Allow"`` allows CronJobs to run concurrently.
        - ``"Forbid"`` forbids concurrent runs, skipping next run if previous hasn't finished yet.
        - ``"Replace"`` cancels currently running job and replaces it with a new one.

        :schema: io.k8s.api.batch.v1.CronJobSpec#concurrencyPolicy
        '''
        result = self._values.get("concurrency_policy")
        return typing.cast(typing.Optional["IoK8SApiBatchV1CronJobSpecConcurrencyPolicy"], result)

    @builtins.property
    def failed_jobs_history_limit(self) -> typing.Optional[jsii.Number]:
        '''The number of failed finished jobs to retain.

        Value must be non-negative integer. Defaults to 1.

        :default: 1.

        :schema: io.k8s.api.batch.v1.CronJobSpec#failedJobsHistoryLimit
        '''
        result = self._values.get("failed_jobs_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def starting_deadline_seconds(self) -> typing.Optional[jsii.Number]:
        '''Optional deadline in seconds for starting the job if it misses scheduled time for any reason.

        Missed jobs executions will be counted as failed ones.

        :schema: io.k8s.api.batch.v1.CronJobSpec#startingDeadlineSeconds
        '''
        result = self._values.get("starting_deadline_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def successful_jobs_history_limit(self) -> typing.Optional[jsii.Number]:
        '''The number of successful finished jobs to retain.

        Value must be non-negative integer. Defaults to 3.

        :default: 3.

        :schema: io.k8s.api.batch.v1.CronJobSpec#successfulJobsHistoryLimit
        '''
        result = self._values.get("successful_jobs_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def suspend(self) -> typing.Optional[builtins.bool]:
        '''This flag tells the controller to suspend subsequent executions, it does not apply to already started executions.

        Defaults to false.

        :default: false.

        :schema: io.k8s.api.batch.v1.CronJobSpec#suspend
        '''
        result = self._values.get("suspend")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CronJobSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CronJobSpecV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "job_template": "jobTemplate",
        "schedule": "schedule",
        "concurrency_policy": "concurrencyPolicy",
        "failed_jobs_history_limit": "failedJobsHistoryLimit",
        "starting_deadline_seconds": "startingDeadlineSeconds",
        "successful_jobs_history_limit": "successfulJobsHistoryLimit",
        "suspend": "suspend",
    },
)
class CronJobSpecV1Beta1:
    def __init__(
        self,
        *,
        job_template: typing.Union["JobTemplateSpecV1Beta1", typing.Dict[str, typing.Any]],
        schedule: builtins.str,
        concurrency_policy: typing.Optional[builtins.str] = None,
        failed_jobs_history_limit: typing.Optional[jsii.Number] = None,
        starting_deadline_seconds: typing.Optional[jsii.Number] = None,
        successful_jobs_history_limit: typing.Optional[jsii.Number] = None,
        suspend: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''CronJobSpec describes how the job execution will look like and when it will actually run.

        :param job_template: Specifies the job that will be created when executing a CronJob.
        :param schedule: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
        :param concurrency_policy: Specifies how to treat concurrent executions of a Job. Valid values are: - "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - "Replace": cancels currently running job and replaces it with a new one
        :param failed_jobs_history_limit: The number of failed finished jobs to retain. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1. Default: 1.
        :param starting_deadline_seconds: Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Missed jobs executions will be counted as failed ones.
        :param successful_jobs_history_limit: The number of successful finished jobs to retain. This is a pointer to distinguish between explicit zero and not specified. Defaults to 3. Default: 3.
        :param suspend: This flag tells the controller to suspend subsequent executions, it does not apply to already started executions. Defaults to false. Default: false.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec
        '''
        if isinstance(job_template, dict):
            job_template = JobTemplateSpecV1Beta1(**job_template)
        if __debug__:
            def stub(
                *,
                job_template: typing.Union[JobTemplateSpecV1Beta1, typing.Dict[str, typing.Any]],
                schedule: builtins.str,
                concurrency_policy: typing.Optional[builtins.str] = None,
                failed_jobs_history_limit: typing.Optional[jsii.Number] = None,
                starting_deadline_seconds: typing.Optional[jsii.Number] = None,
                successful_jobs_history_limit: typing.Optional[jsii.Number] = None,
                suspend: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument job_template", value=job_template, expected_type=type_hints["job_template"])
            check_type(argname="argument schedule", value=schedule, expected_type=type_hints["schedule"])
            check_type(argname="argument concurrency_policy", value=concurrency_policy, expected_type=type_hints["concurrency_policy"])
            check_type(argname="argument failed_jobs_history_limit", value=failed_jobs_history_limit, expected_type=type_hints["failed_jobs_history_limit"])
            check_type(argname="argument starting_deadline_seconds", value=starting_deadline_seconds, expected_type=type_hints["starting_deadline_seconds"])
            check_type(argname="argument successful_jobs_history_limit", value=successful_jobs_history_limit, expected_type=type_hints["successful_jobs_history_limit"])
            check_type(argname="argument suspend", value=suspend, expected_type=type_hints["suspend"])
        self._values: typing.Dict[str, typing.Any] = {
            "job_template": job_template,
            "schedule": schedule,
        }
        if concurrency_policy is not None:
            self._values["concurrency_policy"] = concurrency_policy
        if failed_jobs_history_limit is not None:
            self._values["failed_jobs_history_limit"] = failed_jobs_history_limit
        if starting_deadline_seconds is not None:
            self._values["starting_deadline_seconds"] = starting_deadline_seconds
        if successful_jobs_history_limit is not None:
            self._values["successful_jobs_history_limit"] = successful_jobs_history_limit
        if suspend is not None:
            self._values["suspend"] = suspend

    @builtins.property
    def job_template(self) -> "JobTemplateSpecV1Beta1":
        '''Specifies the job that will be created when executing a CronJob.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#jobTemplate
        '''
        result = self._values.get("job_template")
        assert result is not None, "Required property 'job_template' is missing"
        return typing.cast("JobTemplateSpecV1Beta1", result)

    @builtins.property
    def schedule(self) -> builtins.str:
        '''The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#schedule
        '''
        result = self._values.get("schedule")
        assert result is not None, "Required property 'schedule' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def concurrency_policy(self) -> typing.Optional[builtins.str]:
        '''Specifies how to treat concurrent executions of a Job.

        Valid values are: - "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - "Replace": cancels currently running job and replaces it with a new one

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#concurrencyPolicy
        '''
        result = self._values.get("concurrency_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def failed_jobs_history_limit(self) -> typing.Optional[jsii.Number]:
        '''The number of failed finished jobs to retain.

        This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.

        :default: 1.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#failedJobsHistoryLimit
        '''
        result = self._values.get("failed_jobs_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def starting_deadline_seconds(self) -> typing.Optional[jsii.Number]:
        '''Optional deadline in seconds for starting the job if it misses scheduled time for any reason.

        Missed jobs executions will be counted as failed ones.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#startingDeadlineSeconds
        '''
        result = self._values.get("starting_deadline_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def successful_jobs_history_limit(self) -> typing.Optional[jsii.Number]:
        '''The number of successful finished jobs to retain.

        This is a pointer to distinguish between explicit zero and not specified. Defaults to 3.

        :default: 3.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#successfulJobsHistoryLimit
        '''
        result = self._values.get("successful_jobs_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def suspend(self) -> typing.Optional[builtins.bool]:
        '''This flag tells the controller to suspend subsequent executions, it does not apply to already started executions.

        Defaults to false.

        :default: false.

        :schema: io.k8s.api.batch.v1beta1.CronJobSpec#suspend
        '''
        result = self._values.get("suspend")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CronJobSpecV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CrossVersionObjectReference",
    jsii_struct_bases=[],
    name_mapping={"kind": "kind", "name": "name", "api_version": "apiVersion"},
)
class CrossVersionObjectReference:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CrossVersionObjectReference contains enough information to let you identify the referred resource.

        :param kind: Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        :param name: Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
        :param api_version: API version of the referent.

        :schema: io.k8s.api.autoscaling.v1.CrossVersionObjectReference
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_version is not None:
            self._values["api_version"] = api_version

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind of the referent;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"

        :schema: io.k8s.api.autoscaling.v1.CrossVersionObjectReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the referent;

        More info: http://kubernetes.io/docs/user-guide/identifiers#names

        :schema: io.k8s.api.autoscaling.v1.CrossVersionObjectReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''API version of the referent.

        :schema: io.k8s.api.autoscaling.v1.CrossVersionObjectReference#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CrossVersionObjectReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CrossVersionObjectReferenceV2",
    jsii_struct_bases=[],
    name_mapping={"kind": "kind", "name": "name", "api_version": "apiVersion"},
)
class CrossVersionObjectReferenceV2:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CrossVersionObjectReference contains enough information to let you identify the referred resource.

        :param kind: Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        :param name: Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
        :param api_version: API version of the referent.

        :schema: io.k8s.api.autoscaling.v2.CrossVersionObjectReference
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_version is not None:
            self._values["api_version"] = api_version

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind of the referent;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"

        :schema: io.k8s.api.autoscaling.v2.CrossVersionObjectReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the referent;

        More info: http://kubernetes.io/docs/user-guide/identifiers#names

        :schema: io.k8s.api.autoscaling.v2.CrossVersionObjectReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''API version of the referent.

        :schema: io.k8s.api.autoscaling.v2.CrossVersionObjectReference#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CrossVersionObjectReferenceV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CrossVersionObjectReferenceV2Beta1",
    jsii_struct_bases=[],
    name_mapping={"kind": "kind", "name": "name", "api_version": "apiVersion"},
)
class CrossVersionObjectReferenceV2Beta1:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CrossVersionObjectReference contains enough information to let you identify the referred resource.

        :param kind: Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        :param name: Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
        :param api_version: API version of the referent.

        :schema: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_version is not None:
            self._values["api_version"] = api_version

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind of the referent;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"

        :schema: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the referent;

        More info: http://kubernetes.io/docs/user-guide/identifiers#names

        :schema: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''API version of the referent.

        :schema: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CrossVersionObjectReferenceV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CrossVersionObjectReferenceV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"kind": "kind", "name": "name", "api_version": "apiVersion"},
)
class CrossVersionObjectReferenceV2Beta2:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CrossVersionObjectReference contains enough information to let you identify the referred resource.

        :param kind: Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        :param name: Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
        :param api_version: API version of the referent.

        :schema: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_version is not None:
            self._values["api_version"] = api_version

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind of the referent;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"

        :schema: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the referent;

        More info: http://kubernetes.io/docs/user-guide/identifiers#names

        :schema: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''API version of the referent.

        :schema: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CrossVersionObjectReferenceV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CsiDriverSpec",
    jsii_struct_bases=[],
    name_mapping={
        "attach_required": "attachRequired",
        "fs_group_policy": "fsGroupPolicy",
        "pod_info_on_mount": "podInfoOnMount",
        "requires_republish": "requiresRepublish",
        "storage_capacity": "storageCapacity",
        "token_requests": "tokenRequests",
        "volume_lifecycle_modes": "volumeLifecycleModes",
    },
)
class CsiDriverSpec:
    def __init__(
        self,
        *,
        attach_required: typing.Optional[builtins.bool] = None,
        fs_group_policy: typing.Optional[builtins.str] = None,
        pod_info_on_mount: typing.Optional[builtins.bool] = None,
        requires_republish: typing.Optional[builtins.bool] = None,
        storage_capacity: typing.Optional[builtins.bool] = None,
        token_requests: typing.Optional[typing.Sequence[typing.Union["TokenRequest", typing.Dict[str, typing.Any]]]] = None,
        volume_lifecycle_modes: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''CSIDriverSpec is the specification of a CSIDriver.

        :param attach_required: attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called. This field is immutable.
        :param fs_group_policy: Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details. This field is immutable. Defaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce. Default: ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.
        :param pod_info_on_mount: If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. "csi.storage.k8s.io/pod.name": pod.Name "csi.storage.k8s.io/pod.namespace": pod.Namespace "csi.storage.k8s.io/pod.uid": string(pod.UID) "csi.storage.k8s.io/ephemeral": "true" if the volume is an ephemeral inline volume defined by a CSIVolumeSource, otherwise "false". "csi.storage.k8s.io/ephemeral" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the "Persistent" and "Ephemeral" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver. This field is immutable. Default: false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. "csi.storage.k8s.io/pod.name": pod.Name "csi.storage.k8s.io/pod.namespace": pod.Namespace "csi.storage.k8s.io/pod.uid": string(pod.UID) "csi.storage.k8s.io/ephemeral": "true" if the volume is an ephemeral inline volume
        :param requires_republish: RequiresRepublish indicates the CSI driver wants ``NodePublishVolume`` being periodically called to reflect any possible change in the mounted volume. This field defaults to false. Note: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.
        :param storage_capacity: If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information. The check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object. Alternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published. This field was immutable in Kubernetes <= 1.22 and now is mutable. This is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.
        :param token_requests: TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: "csi.storage.k8s.io/serviceAccount.tokens": { "": { "token": , "expirationTimestamp": , }, ... } Note: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.
        :param volume_lifecycle_modes: volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is "Persistent", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta. This field is immutable.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec
        '''
        if __debug__:
            def stub(
                *,
                attach_required: typing.Optional[builtins.bool] = None,
                fs_group_policy: typing.Optional[builtins.str] = None,
                pod_info_on_mount: typing.Optional[builtins.bool] = None,
                requires_republish: typing.Optional[builtins.bool] = None,
                storage_capacity: typing.Optional[builtins.bool] = None,
                token_requests: typing.Optional[typing.Sequence[typing.Union[TokenRequest, typing.Dict[str, typing.Any]]]] = None,
                volume_lifecycle_modes: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument attach_required", value=attach_required, expected_type=type_hints["attach_required"])
            check_type(argname="argument fs_group_policy", value=fs_group_policy, expected_type=type_hints["fs_group_policy"])
            check_type(argname="argument pod_info_on_mount", value=pod_info_on_mount, expected_type=type_hints["pod_info_on_mount"])
            check_type(argname="argument requires_republish", value=requires_republish, expected_type=type_hints["requires_republish"])
            check_type(argname="argument storage_capacity", value=storage_capacity, expected_type=type_hints["storage_capacity"])
            check_type(argname="argument token_requests", value=token_requests, expected_type=type_hints["token_requests"])
            check_type(argname="argument volume_lifecycle_modes", value=volume_lifecycle_modes, expected_type=type_hints["volume_lifecycle_modes"])
        self._values: typing.Dict[str, typing.Any] = {}
        if attach_required is not None:
            self._values["attach_required"] = attach_required
        if fs_group_policy is not None:
            self._values["fs_group_policy"] = fs_group_policy
        if pod_info_on_mount is not None:
            self._values["pod_info_on_mount"] = pod_info_on_mount
        if requires_republish is not None:
            self._values["requires_republish"] = requires_republish
        if storage_capacity is not None:
            self._values["storage_capacity"] = storage_capacity
        if token_requests is not None:
            self._values["token_requests"] = token_requests
        if volume_lifecycle_modes is not None:
            self._values["volume_lifecycle_modes"] = volume_lifecycle_modes

    @builtins.property
    def attach_required(self) -> typing.Optional[builtins.bool]:
        '''attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting.

        The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.

        This field is immutable.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#attachRequired
        '''
        result = self._values.get("attach_required")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def fs_group_policy(self) -> typing.Optional[builtins.str]:
        '''Defines if the underlying volume supports changing ownership and permission of the volume before being mounted.

        Refer to the specific FSGroupPolicy values for additional details.

        This field is immutable.

        Defaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.

        :default: ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#fsGroupPolicy
        '''
        result = self._values.get("fs_group_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def pod_info_on_mount(self) -> typing.Optional[builtins.bool]:
        '''If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. "csi.storage.k8s.io/pod.name": pod.Name "csi.storage.k8s.io/pod.namespace": pod.Namespace "csi.storage.k8s.io/pod.uid": string(pod.UID) "csi.storage.k8s.io/ephemeral": "true" if the volume is an ephemeral inline volume defined by a CSIVolumeSource, otherwise "false".

        "csi.storage.k8s.io/ephemeral" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the "Persistent" and "Ephemeral" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.

        This field is immutable.

        :default: false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. "csi.storage.k8s.io/pod.name": pod.Name "csi.storage.k8s.io/pod.namespace": pod.Namespace "csi.storage.k8s.io/pod.uid": string(pod.UID) "csi.storage.k8s.io/ephemeral": "true" if the volume is an ephemeral inline volume

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#podInfoOnMount
        '''
        result = self._values.get("pod_info_on_mount")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def requires_republish(self) -> typing.Optional[builtins.bool]:
        '''RequiresRepublish indicates the CSI driver wants ``NodePublishVolume`` being periodically called to reflect any possible change in the mounted volume.

        This field defaults to false.

        Note: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#requiresRepublish
        '''
        result = self._values.get("requires_republish")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def storage_capacity(self) -> typing.Optional[builtins.bool]:
        '''If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.

        The check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.

        Alternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.

        This field was immutable in Kubernetes <= 1.22 and now is mutable.

        This is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#storageCapacity
        '''
        result = self._values.get("storage_capacity")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def token_requests(self) -> typing.Optional[typing.List["TokenRequest"]]:
        '''TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication.

        Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: "csi.storage.k8s.io/serviceAccount.tokens": {
        "": {
        "token": ,
        "expirationTimestamp": ,
        },
        ...
        }

        Note: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#tokenRequests
        '''
        result = self._values.get("token_requests")
        return typing.cast(typing.Optional[typing.List["TokenRequest"]], result)

    @builtins.property
    def volume_lifecycle_modes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''volumeLifecycleModes defines what kind of volumes this CSI volume driver supports.

        The default if the list is empty is "Persistent", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.

        This field is immutable.

        :schema: io.k8s.api.storage.v1.CSIDriverSpec#volumeLifecycleModes
        '''
        result = self._values.get("volume_lifecycle_modes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CsiDriverSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CsiNodeDriver",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "node_id": "nodeId",
        "allocatable": "allocatable",
        "topology_keys": "topologyKeys",
    },
)
class CsiNodeDriver:
    def __init__(
        self,
        *,
        name: builtins.str,
        node_id: builtins.str,
        allocatable: typing.Optional[typing.Union["VolumeNodeResources", typing.Dict[str, typing.Any]]] = None,
        topology_keys: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''CSINodeDriver holds information about the specification of one CSI driver installed on a node.

        :param name: This is the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.
        :param node_id: nodeID of the node from the driver point of view. This field enables Kubernetes to communicate with storage systems that do not share the same nomenclature for nodes. For example, Kubernetes may refer to a given node as "node1", but the storage system may refer to the same node as "nodeA". When Kubernetes issues a command to the storage system to attach a volume to a specific node, it can use this field to refer to the node name using the ID that the storage system will understand, e.g. "nodeA" instead of "node1". This field is required.
        :param allocatable: allocatable represents the volume resources of a node that are available for scheduling. This field is beta.
        :param topology_keys: topologyKeys is the list of keys supported by the driver. When a driver is initialized on a cluster, it provides a set of topology keys that it understands (e.g. "company.com/zone", "company.com/region"). When a driver is initialized on a node, it provides the same topology keys along with values. Kubelet will expose these topology keys as labels on its own node object. When Kubernetes does topology aware provisioning, it can use this list to determine which labels it should retrieve from the node object and pass back to the driver. It is possible for different nodes to use different topology keys. This can be empty if driver does not support topology.

        :schema: io.k8s.api.storage.v1.CSINodeDriver
        '''
        if isinstance(allocatable, dict):
            allocatable = VolumeNodeResources(**allocatable)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                node_id: builtins.str,
                allocatable: typing.Optional[typing.Union[VolumeNodeResources, typing.Dict[str, typing.Any]]] = None,
                topology_keys: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument node_id", value=node_id, expected_type=type_hints["node_id"])
            check_type(argname="argument allocatable", value=allocatable, expected_type=type_hints["allocatable"])
            check_type(argname="argument topology_keys", value=topology_keys, expected_type=type_hints["topology_keys"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "node_id": node_id,
        }
        if allocatable is not None:
            self._values["allocatable"] = allocatable
        if topology_keys is not None:
            self._values["topology_keys"] = topology_keys

    @builtins.property
    def name(self) -> builtins.str:
        '''This is the name of the CSI driver that this object refers to.

        This MUST be the same name returned by the CSI GetPluginName() call for that driver.

        :schema: io.k8s.api.storage.v1.CSINodeDriver#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def node_id(self) -> builtins.str:
        '''nodeID of the node from the driver point of view.

        This field enables Kubernetes to communicate with storage systems that do not share the same nomenclature for nodes. For example, Kubernetes may refer to a given node as "node1", but the storage system may refer to the same node as "nodeA". When Kubernetes issues a command to the storage system to attach a volume to a specific node, it can use this field to refer to the node name using the ID that the storage system will understand, e.g. "nodeA" instead of "node1". This field is required.

        :schema: io.k8s.api.storage.v1.CSINodeDriver#nodeID
        '''
        result = self._values.get("node_id")
        assert result is not None, "Required property 'node_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def allocatable(self) -> typing.Optional["VolumeNodeResources"]:
        '''allocatable represents the volume resources of a node that are available for scheduling.

        This field is beta.

        :schema: io.k8s.api.storage.v1.CSINodeDriver#allocatable
        '''
        result = self._values.get("allocatable")
        return typing.cast(typing.Optional["VolumeNodeResources"], result)

    @builtins.property
    def topology_keys(self) -> typing.Optional[typing.List[builtins.str]]:
        '''topologyKeys is the list of keys supported by the driver.

        When a driver is initialized on a cluster, it provides a set of topology keys that it understands (e.g. "company.com/zone", "company.com/region"). When a driver is initialized on a node, it provides the same topology keys along with values. Kubelet will expose these topology keys as labels on its own node object. When Kubernetes does topology aware provisioning, it can use this list to determine which labels it should retrieve from the node object and pass back to the driver. It is possible for different nodes to use different topology keys. This can be empty if driver does not support topology.

        :schema: io.k8s.api.storage.v1.CSINodeDriver#topologyKeys
        '''
        result = self._values.get("topology_keys")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CsiNodeDriver(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CsiNodeSpec",
    jsii_struct_bases=[],
    name_mapping={"drivers": "drivers"},
)
class CsiNodeSpec:
    def __init__(
        self,
        *,
        drivers: typing.Sequence[typing.Union[CsiNodeDriver, typing.Dict[str, typing.Any]]],
    ) -> None:
        '''CSINodeSpec holds information about the specification of all CSI drivers installed on a node.

        :param drivers: drivers is a list of information of all CSI Drivers existing on a node. If all drivers in the list are uninstalled, this can become empty.

        :schema: io.k8s.api.storage.v1.CSINodeSpec
        '''
        if __debug__:
            def stub(
                *,
                drivers: typing.Sequence[typing.Union[CsiNodeDriver, typing.Dict[str, typing.Any]]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument drivers", value=drivers, expected_type=type_hints["drivers"])
        self._values: typing.Dict[str, typing.Any] = {
            "drivers": drivers,
        }

    @builtins.property
    def drivers(self) -> typing.List[CsiNodeDriver]:
        '''drivers is a list of information of all CSI Drivers existing on a node.

        If all drivers in the list are uninstalled, this can become empty.

        :schema: io.k8s.api.storage.v1.CSINodeSpec#drivers
        '''
        result = self._values.get("drivers")
        assert result is not None, "Required property 'drivers' is missing"
        return typing.cast(typing.List[CsiNodeDriver], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CsiNodeSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CsiPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "driver": "driver",
        "volume_handle": "volumeHandle",
        "controller_expand_secret_ref": "controllerExpandSecretRef",
        "controller_publish_secret_ref": "controllerPublishSecretRef",
        "fs_type": "fsType",
        "node_publish_secret_ref": "nodePublishSecretRef",
        "node_stage_secret_ref": "nodeStageSecretRef",
        "read_only": "readOnly",
        "volume_attributes": "volumeAttributes",
    },
)
class CsiPersistentVolumeSource:
    def __init__(
        self,
        *,
        driver: builtins.str,
        volume_handle: builtins.str,
        controller_expand_secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
        controller_publish_secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
        fs_type: typing.Optional[builtins.str] = None,
        node_publish_secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
        node_stage_secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
        read_only: typing.Optional[builtins.bool] = None,
        volume_attributes: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
    ) -> None:
        '''Represents storage that is managed by an external CSI volume driver (Beta feature).

        :param driver: Driver is the name of the driver to use for this volume. Required.
        :param volume_handle: VolumeHandle is the unique volume name returned by the CSI volume plugin’s CreateVolume to refer to the volume on all subsequent calls. Required.
        :param controller_expand_secret_ref: ControllerExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerExpandVolume call. This is an alpha field and requires enabling ExpandCSIVolumes feature gate. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.
        :param controller_publish_secret_ref: ControllerPublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerPublishVolume and ControllerUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs".
        :param node_publish_secret_ref: NodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.
        :param node_stage_secret_ref: NodeStageSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeStageVolume and NodeStageVolume and NodeUnstageVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.
        :param read_only: Optional: The value to pass to ControllerPublishVolumeRequest. Defaults to false (read/write). Default: false (read/write).
        :param volume_attributes: Attributes of the volume to publish.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource
        '''
        if isinstance(controller_expand_secret_ref, dict):
            controller_expand_secret_ref = SecretReference(**controller_expand_secret_ref)
        if isinstance(controller_publish_secret_ref, dict):
            controller_publish_secret_ref = SecretReference(**controller_publish_secret_ref)
        if isinstance(node_publish_secret_ref, dict):
            node_publish_secret_ref = SecretReference(**node_publish_secret_ref)
        if isinstance(node_stage_secret_ref, dict):
            node_stage_secret_ref = SecretReference(**node_stage_secret_ref)
        if __debug__:
            def stub(
                *,
                driver: builtins.str,
                volume_handle: builtins.str,
                controller_expand_secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
                controller_publish_secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
                fs_type: typing.Optional[builtins.str] = None,
                node_publish_secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
                node_stage_secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
                read_only: typing.Optional[builtins.bool] = None,
                volume_attributes: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument driver", value=driver, expected_type=type_hints["driver"])
            check_type(argname="argument volume_handle", value=volume_handle, expected_type=type_hints["volume_handle"])
            check_type(argname="argument controller_expand_secret_ref", value=controller_expand_secret_ref, expected_type=type_hints["controller_expand_secret_ref"])
            check_type(argname="argument controller_publish_secret_ref", value=controller_publish_secret_ref, expected_type=type_hints["controller_publish_secret_ref"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument node_publish_secret_ref", value=node_publish_secret_ref, expected_type=type_hints["node_publish_secret_ref"])
            check_type(argname="argument node_stage_secret_ref", value=node_stage_secret_ref, expected_type=type_hints["node_stage_secret_ref"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument volume_attributes", value=volume_attributes, expected_type=type_hints["volume_attributes"])
        self._values: typing.Dict[str, typing.Any] = {
            "driver": driver,
            "volume_handle": volume_handle,
        }
        if controller_expand_secret_ref is not None:
            self._values["controller_expand_secret_ref"] = controller_expand_secret_ref
        if controller_publish_secret_ref is not None:
            self._values["controller_publish_secret_ref"] = controller_publish_secret_ref
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if node_publish_secret_ref is not None:
            self._values["node_publish_secret_ref"] = node_publish_secret_ref
        if node_stage_secret_ref is not None:
            self._values["node_stage_secret_ref"] = node_stage_secret_ref
        if read_only is not None:
            self._values["read_only"] = read_only
        if volume_attributes is not None:
            self._values["volume_attributes"] = volume_attributes

    @builtins.property
    def driver(self) -> builtins.str:
        '''Driver is the name of the driver to use for this volume.

        Required.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#driver
        '''
        result = self._values.get("driver")
        assert result is not None, "Required property 'driver' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def volume_handle(self) -> builtins.str:
        '''VolumeHandle is the unique volume name returned by the CSI volume plugin’s CreateVolume to refer to the volume on all subsequent calls.

        Required.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#volumeHandle
        '''
        result = self._values.get("volume_handle")
        assert result is not None, "Required property 'volume_handle' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def controller_expand_secret_ref(self) -> typing.Optional["SecretReference"]:
        '''ControllerExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerExpandVolume call.

        This is an alpha field and requires enabling ExpandCSIVolumes feature gate. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#controllerExpandSecretRef
        '''
        result = self._values.get("controller_expand_secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    @builtins.property
    def controller_publish_secret_ref(self) -> typing.Optional["SecretReference"]:
        '''ControllerPublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerPublishVolume and ControllerUnpublishVolume calls.

        This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#controllerPublishSecretRef
        '''
        result = self._values.get("controller_publish_secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs".

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_publish_secret_ref(self) -> typing.Optional["SecretReference"]:
        '''NodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls.

        This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#nodePublishSecretRef
        '''
        result = self._values.get("node_publish_secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    @builtins.property
    def node_stage_secret_ref(self) -> typing.Optional["SecretReference"]:
        '''NodeStageSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeStageVolume and NodeStageVolume and NodeUnstageVolume calls.

        This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#nodeStageSecretRef
        '''
        result = self._values.get("node_stage_secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: The value to pass to ControllerPublishVolumeRequest.

        Defaults to false (read/write).

        :default: false (read/write).

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def volume_attributes(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Attributes of the volume to publish.

        :schema: io.k8s.api.core.v1.CSIPersistentVolumeSource#volumeAttributes
        '''
        result = self._values.get("volume_attributes")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CsiPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CsiVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "driver": "driver",
        "fs_type": "fsType",
        "node_publish_secret_ref": "nodePublishSecretRef",
        "read_only": "readOnly",
        "volume_attributes": "volumeAttributes",
    },
)
class CsiVolumeSource:
    def __init__(
        self,
        *,
        driver: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        node_publish_secret_ref: typing.Optional[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]] = None,
        read_only: typing.Optional[builtins.bool] = None,
        volume_attributes: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
    ) -> None:
        '''Represents a source location of a volume to mount, managed by an external CSI driver.

        :param driver: Driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster.
        :param fs_type: Filesystem type to mount. Ex. "ext4", "xfs", "ntfs". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply.
        :param node_publish_secret_ref: NodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed.
        :param read_only: Specifies a read-only configuration for the volume. Defaults to false (read/write). Default: false (read/write).
        :param volume_attributes: VolumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values.

        :schema: io.k8s.api.core.v1.CSIVolumeSource
        '''
        if isinstance(node_publish_secret_ref, dict):
            node_publish_secret_ref = LocalObjectReference(**node_publish_secret_ref)
        if __debug__:
            def stub(
                *,
                driver: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                node_publish_secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                read_only: typing.Optional[builtins.bool] = None,
                volume_attributes: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument driver", value=driver, expected_type=type_hints["driver"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument node_publish_secret_ref", value=node_publish_secret_ref, expected_type=type_hints["node_publish_secret_ref"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument volume_attributes", value=volume_attributes, expected_type=type_hints["volume_attributes"])
        self._values: typing.Dict[str, typing.Any] = {
            "driver": driver,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if node_publish_secret_ref is not None:
            self._values["node_publish_secret_ref"] = node_publish_secret_ref
        if read_only is not None:
            self._values["read_only"] = read_only
        if volume_attributes is not None:
            self._values["volume_attributes"] = volume_attributes

    @builtins.property
    def driver(self) -> builtins.str:
        '''Driver is the name of the CSI driver that handles this volume.

        Consult with your admin for the correct name as registered in the cluster.

        :schema: io.k8s.api.core.v1.CSIVolumeSource#driver
        '''
        result = self._values.get("driver")
        assert result is not None, "Required property 'driver' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Ex. "ext4", "xfs", "ntfs". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply.

        :schema: io.k8s.api.core.v1.CSIVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_publish_secret_ref(self) -> typing.Optional["LocalObjectReference"]:
        '''NodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls.

        This field is optional, and  may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed.

        :schema: io.k8s.api.core.v1.CSIVolumeSource#nodePublishSecretRef
        '''
        result = self._values.get("node_publish_secret_ref")
        return typing.cast(typing.Optional["LocalObjectReference"], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Specifies a read-only configuration for the volume.

        Defaults to false (read/write).

        :default: false (read/write).

        :schema: io.k8s.api.core.v1.CSIVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def volume_attributes(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''VolumeAttributes stores driver-specific properties that are passed to the CSI driver.

        Consult your driver's documentation for supported values.

        :schema: io.k8s.api.core.v1.CSIVolumeSource#volumeAttributes
        '''
        result = self._values.get("volume_attributes")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CsiVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceColumnDefinition",
    jsii_struct_bases=[],
    name_mapping={
        "json_path": "jsonPath",
        "name": "name",
        "type": "type",
        "description": "description",
        "format": "format",
        "priority": "priority",
    },
)
class CustomResourceColumnDefinition:
    def __init__(
        self,
        *,
        json_path: builtins.str,
        name: builtins.str,
        type: builtins.str,
        description: typing.Optional[builtins.str] = None,
        format: typing.Optional[builtins.str] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''CustomResourceColumnDefinition specifies a column for server side printing.

        :param json_path: jsonPath is a simple JSON path (i.e. with array notation) which is evaluated against each custom resource to produce the value for this column.
        :param name: name is a human readable name for the column.
        :param type: type is an OpenAPI type definition for this column. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details.
        :param description: description is a human readable description of this column.
        :param format: format is an optional OpenAPI type definition for this column. The 'name' format is applied to the primary identifier column to assist in clients identifying column is the resource name. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details.
        :param priority: priority is an integer defining the relative importance of this column compared to others. Lower numbers are considered higher priority. Columns that may be omitted in limited space scenarios should be given a priority greater than 0.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition
        '''
        if __debug__:
            def stub(
                *,
                json_path: builtins.str,
                name: builtins.str,
                type: builtins.str,
                description: typing.Optional[builtins.str] = None,
                format: typing.Optional[builtins.str] = None,
                priority: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument json_path", value=json_path, expected_type=type_hints["json_path"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument description", value=description, expected_type=type_hints["description"])
            check_type(argname="argument format", value=format, expected_type=type_hints["format"])
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
        self._values: typing.Dict[str, typing.Any] = {
            "json_path": json_path,
            "name": name,
            "type": type,
        }
        if description is not None:
            self._values["description"] = description
        if format is not None:
            self._values["format"] = format
        if priority is not None:
            self._values["priority"] = priority

    @builtins.property
    def json_path(self) -> builtins.str:
        '''jsonPath is a simple JSON path (i.e. with array notation) which is evaluated against each custom resource to produce the value for this column.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition#jsonPath
        '''
        result = self._values.get("json_path")
        assert result is not None, "Required property 'json_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''name is a human readable name for the column.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def type(self) -> builtins.str:
        '''type is an OpenAPI type definition for this column.

        See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''description is a human readable description of this column.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition#description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def format(self) -> typing.Optional[builtins.str]:
        '''format is an optional OpenAPI type definition for this column.

        The 'name' format is applied to the primary identifier column to assist in clients identifying column is the resource name. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition#format
        '''
        result = self._values.get("format")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''priority is an integer defining the relative importance of this column compared to others.

        Lower numbers are considered higher priority. Columns that may be omitted in limited space scenarios should be given a priority greater than 0.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceColumnDefinition#priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceColumnDefinition(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceConversion",
    jsii_struct_bases=[],
    name_mapping={"strategy": "strategy", "webhook": "webhook"},
)
class CustomResourceConversion:
    def __init__(
        self,
        *,
        strategy: builtins.str,
        webhook: typing.Optional[typing.Union["WebhookConversion", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CustomResourceConversion describes how to convert different versions of a CR.

        :param strategy: strategy specifies how custom resources are converted between versions. Allowed values are: - ``None``: The converter only change the apiVersion and would not touch any other field in the custom resource. - ``Webhook``: API Server will call to an external webhook to do the conversion. Additional information is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set.
        :param webhook: webhook describes how to call the conversion webhook. Required when ``strategy`` is set to ``Webhook``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceConversion
        '''
        if isinstance(webhook, dict):
            webhook = WebhookConversion(**webhook)
        if __debug__:
            def stub(
                *,
                strategy: builtins.str,
                webhook: typing.Optional[typing.Union[WebhookConversion, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument strategy", value=strategy, expected_type=type_hints["strategy"])
            check_type(argname="argument webhook", value=webhook, expected_type=type_hints["webhook"])
        self._values: typing.Dict[str, typing.Any] = {
            "strategy": strategy,
        }
        if webhook is not None:
            self._values["webhook"] = webhook

    @builtins.property
    def strategy(self) -> builtins.str:
        '''strategy specifies how custom resources are converted between versions.

        Allowed values are: - ``None``: The converter only change the apiVersion and would not touch any other field in the custom resource. - ``Webhook``: API Server will call to an external webhook to do the conversion. Additional information
        is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceConversion#strategy
        '''
        result = self._values.get("strategy")
        assert result is not None, "Required property 'strategy' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def webhook(self) -> typing.Optional["WebhookConversion"]:
        '''webhook describes how to call the conversion webhook.

        Required when ``strategy`` is set to ``Webhook``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceConversion#webhook
        '''
        result = self._values.get("webhook")
        return typing.cast(typing.Optional["WebhookConversion"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceConversion(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceDefinitionNames",
    jsii_struct_bases=[],
    name_mapping={
        "kind": "kind",
        "plural": "plural",
        "categories": "categories",
        "list_kind": "listKind",
        "short_names": "shortNames",
        "singular": "singular",
    },
)
class CustomResourceDefinitionNames:
    def __init__(
        self,
        *,
        kind: builtins.str,
        plural: builtins.str,
        categories: typing.Optional[typing.Sequence[builtins.str]] = None,
        list_kind: typing.Optional[builtins.str] = None,
        short_names: typing.Optional[typing.Sequence[builtins.str]] = None,
        singular: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition.

        :param kind: kind is the serialized kind of the resource. It is normally CamelCase and singular. Custom resource instances will use this value as the ``kind`` attribute in API calls.
        :param plural: plural is the plural name of the resource to serve. The custom resources are served under ``/apis/<group>/<version>/.../<plural>``. Must match the name of the CustomResourceDefinition (in the form ``<names.plural>.<group>``). Must be all lowercase.
        :param categories: categories is a list of grouped resources this custom resource belongs to (e.g. 'all'). This is published in API discovery documents, and used by clients to support invocations like ``kubectl get all``.
        :param list_kind: listKind is the serialized kind of the list for this resource. Defaults to "``kind``List". Default: kind`List".
        :param short_names: shortNames are short names for the resource, exposed in API discovery documents, and used by clients to support invocations like ``kubectl get <shortname>``. It must be all lowercase.
        :param singular: singular is the singular name of the resource. It must be all lowercase. Defaults to lowercased ``kind``. Default: lowercased ``kind``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                plural: builtins.str,
                categories: typing.Optional[typing.Sequence[builtins.str]] = None,
                list_kind: typing.Optional[builtins.str] = None,
                short_names: typing.Optional[typing.Sequence[builtins.str]] = None,
                singular: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument plural", value=plural, expected_type=type_hints["plural"])
            check_type(argname="argument categories", value=categories, expected_type=type_hints["categories"])
            check_type(argname="argument list_kind", value=list_kind, expected_type=type_hints["list_kind"])
            check_type(argname="argument short_names", value=short_names, expected_type=type_hints["short_names"])
            check_type(argname="argument singular", value=singular, expected_type=type_hints["singular"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "plural": plural,
        }
        if categories is not None:
            self._values["categories"] = categories
        if list_kind is not None:
            self._values["list_kind"] = list_kind
        if short_names is not None:
            self._values["short_names"] = short_names
        if singular is not None:
            self._values["singular"] = singular

    @builtins.property
    def kind(self) -> builtins.str:
        '''kind is the serialized kind of the resource.

        It is normally CamelCase and singular. Custom resource instances will use this value as the ``kind`` attribute in API calls.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def plural(self) -> builtins.str:
        '''plural is the plural name of the resource to serve.

        The custom resources are served under ``/apis/<group>/<version>/.../<plural>``. Must match the name of the CustomResourceDefinition (in the form ``<names.plural>.<group>``). Must be all lowercase.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames#plural
        '''
        result = self._values.get("plural")
        assert result is not None, "Required property 'plural' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def categories(self) -> typing.Optional[typing.List[builtins.str]]:
        '''categories is a list of grouped resources this custom resource belongs to (e.g. 'all'). This is published in API discovery documents, and used by clients to support invocations like ``kubectl get all``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames#categories
        '''
        result = self._values.get("categories")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def list_kind(self) -> typing.Optional[builtins.str]:
        '''listKind is the serialized kind of the list for this resource.

        Defaults to "``kind``List".

        :default: kind`List".

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames#listKind
        '''
        result = self._values.get("list_kind")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def short_names(self) -> typing.Optional[typing.List[builtins.str]]:
        '''shortNames are short names for the resource, exposed in API discovery documents, and used by clients to support invocations like ``kubectl get <shortname>``.

        It must be all lowercase.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames#shortNames
        '''
        result = self._values.get("short_names")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def singular(self) -> typing.Optional[builtins.str]:
        '''singular is the singular name of the resource.

        It must be all lowercase. Defaults to lowercased ``kind``.

        :default: lowercased ``kind``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionNames#singular
        '''
        result = self._values.get("singular")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceDefinitionNames(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceDefinitionSpec",
    jsii_struct_bases=[],
    name_mapping={
        "group": "group",
        "names": "names",
        "scope": "scope",
        "versions": "versions",
        "conversion": "conversion",
        "preserve_unknown_fields": "preserveUnknownFields",
    },
)
class CustomResourceDefinitionSpec:
    def __init__(
        self,
        *,
        group: builtins.str,
        names: typing.Union[CustomResourceDefinitionNames, typing.Dict[str, typing.Any]],
        scope: builtins.str,
        versions: typing.Sequence[typing.Union["CustomResourceDefinitionVersion", typing.Dict[str, typing.Any]]],
        conversion: typing.Optional[typing.Union[CustomResourceConversion, typing.Dict[str, typing.Any]]] = None,
        preserve_unknown_fields: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''CustomResourceDefinitionSpec describes how a user wants their resource to appear.

        :param group: group is the API group of the defined custom resource. The custom resources are served under ``/apis/<group>/...``. Must match the name of the CustomResourceDefinition (in the form ``<names.plural>.<group>``).
        :param names: names specify the resource and kind names for the custom resource.
        :param scope: scope indicates whether the defined custom resource is cluster- or namespace-scoped. Allowed values are ``Cluster`` and ``Namespaced``.
        :param versions: versions is the list of all API versions of the defined custom resource. Version names are used to compute the order in which served versions are listed in API discovery. If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version), then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing major version, then minor version. An example sorted list of versions: v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.
        :param conversion: conversion defines conversion settings for the CRD.
        :param preserve_unknown_fields: preserveUnknownFields indicates that object fields which are not specified in the OpenAPI schema should be preserved when persisting to storage. apiVersion, kind, metadata and known fields inside metadata are always preserved. This field is deprecated in favor of setting ``x-preserve-unknown-fields`` to true in ``spec.versions[*].schema.openAPIV3Schema``. See https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#pruning-versus-preserving-unknown-fields for details.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec
        '''
        if isinstance(names, dict):
            names = CustomResourceDefinitionNames(**names)
        if isinstance(conversion, dict):
            conversion = CustomResourceConversion(**conversion)
        if __debug__:
            def stub(
                *,
                group: builtins.str,
                names: typing.Union[CustomResourceDefinitionNames, typing.Dict[str, typing.Any]],
                scope: builtins.str,
                versions: typing.Sequence[typing.Union[CustomResourceDefinitionVersion, typing.Dict[str, typing.Any]]],
                conversion: typing.Optional[typing.Union[CustomResourceConversion, typing.Dict[str, typing.Any]]] = None,
                preserve_unknown_fields: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument names", value=names, expected_type=type_hints["names"])
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument versions", value=versions, expected_type=type_hints["versions"])
            check_type(argname="argument conversion", value=conversion, expected_type=type_hints["conversion"])
            check_type(argname="argument preserve_unknown_fields", value=preserve_unknown_fields, expected_type=type_hints["preserve_unknown_fields"])
        self._values: typing.Dict[str, typing.Any] = {
            "group": group,
            "names": names,
            "scope": scope,
            "versions": versions,
        }
        if conversion is not None:
            self._values["conversion"] = conversion
        if preserve_unknown_fields is not None:
            self._values["preserve_unknown_fields"] = preserve_unknown_fields

    @builtins.property
    def group(self) -> builtins.str:
        '''group is the API group of the defined custom resource.

        The custom resources are served under ``/apis/<group>/...``. Must match the name of the CustomResourceDefinition (in the form ``<names.plural>.<group>``).

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec#group
        '''
        result = self._values.get("group")
        assert result is not None, "Required property 'group' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def names(self) -> CustomResourceDefinitionNames:
        '''names specify the resource and kind names for the custom resource.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec#names
        '''
        result = self._values.get("names")
        assert result is not None, "Required property 'names' is missing"
        return typing.cast(CustomResourceDefinitionNames, result)

    @builtins.property
    def scope(self) -> builtins.str:
        '''scope indicates whether the defined custom resource is cluster- or namespace-scoped.

        Allowed values are ``Cluster`` and ``Namespaced``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec#scope
        '''
        result = self._values.get("scope")
        assert result is not None, "Required property 'scope' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def versions(self) -> typing.List["CustomResourceDefinitionVersion"]:
        '''versions is the list of all API versions of the defined custom resource.

        Version names are used to compute the order in which served versions are listed in API discovery. If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version), then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing major version, then minor version. An example sorted list of versions: v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec#versions
        '''
        result = self._values.get("versions")
        assert result is not None, "Required property 'versions' is missing"
        return typing.cast(typing.List["CustomResourceDefinitionVersion"], result)

    @builtins.property
    def conversion(self) -> typing.Optional[CustomResourceConversion]:
        '''conversion defines conversion settings for the CRD.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec#conversion
        '''
        result = self._values.get("conversion")
        return typing.cast(typing.Optional[CustomResourceConversion], result)

    @builtins.property
    def preserve_unknown_fields(self) -> typing.Optional[builtins.bool]:
        '''preserveUnknownFields indicates that object fields which are not specified in the OpenAPI schema should be preserved when persisting to storage.

        apiVersion, kind, metadata and known fields inside metadata are always preserved. This field is deprecated in favor of setting ``x-preserve-unknown-fields`` to true in ``spec.versions[*].schema.openAPIV3Schema``. See https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#pruning-versus-preserving-unknown-fields for details.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionSpec#preserveUnknownFields
        '''
        result = self._values.get("preserve_unknown_fields")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceDefinitionSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceDefinitionVersion",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "served": "served",
        "storage": "storage",
        "additional_printer_columns": "additionalPrinterColumns",
        "deprecated": "deprecated",
        "deprecation_warning": "deprecationWarning",
        "schema": "schema",
        "subresources": "subresources",
    },
)
class CustomResourceDefinitionVersion:
    def __init__(
        self,
        *,
        name: builtins.str,
        served: builtins.bool,
        storage: builtins.bool,
        additional_printer_columns: typing.Optional[typing.Sequence[typing.Union[CustomResourceColumnDefinition, typing.Dict[str, typing.Any]]]] = None,
        deprecated: typing.Optional[builtins.bool] = None,
        deprecation_warning: typing.Optional[builtins.str] = None,
        schema: typing.Optional[typing.Union["CustomResourceValidation", typing.Dict[str, typing.Any]]] = None,
        subresources: typing.Optional[typing.Union["CustomResourceSubresources", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CustomResourceDefinitionVersion describes a version for CRD.

        :param name: name is the version name, e.g. “v1”, “v2beta1”, etc. The custom resources are served under this version at ``/apis/<group>/<version>/...`` if ``served`` is true.
        :param served: served is a flag enabling/disabling this version from being served via REST APIs.
        :param storage: storage indicates this version should be used when persisting custom resources to storage. There must be exactly one version with storage=true.
        :param additional_printer_columns: additionalPrinterColumns specifies additional columns returned in Table output. See https://kubernetes.io/docs/reference/using-api/api-concepts/#receiving-resources-as-tables for details. If no columns are specified, a single column displaying the age of the custom resource is used.
        :param deprecated: deprecated indicates this version of the custom resource API is deprecated. When set to true, API requests to this version receive a warning header in the server response. Defaults to false. Default: false.
        :param deprecation_warning: deprecationWarning overrides the default warning returned to API clients. May only be set when ``deprecated`` is true. The default warning indicates this version is deprecated and recommends use of the newest served version of equal or greater stability, if one exists.
        :param schema: schema describes the schema used for validation, pruning, and defaulting of this version of the custom resource.
        :param subresources: subresources specify what subresources this version of the defined custom resource have.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion
        '''
        if isinstance(schema, dict):
            schema = CustomResourceValidation(**schema)
        if isinstance(subresources, dict):
            subresources = CustomResourceSubresources(**subresources)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                served: builtins.bool,
                storage: builtins.bool,
                additional_printer_columns: typing.Optional[typing.Sequence[typing.Union[CustomResourceColumnDefinition, typing.Dict[str, typing.Any]]]] = None,
                deprecated: typing.Optional[builtins.bool] = None,
                deprecation_warning: typing.Optional[builtins.str] = None,
                schema: typing.Optional[typing.Union[CustomResourceValidation, typing.Dict[str, typing.Any]]] = None,
                subresources: typing.Optional[typing.Union[CustomResourceSubresources, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument served", value=served, expected_type=type_hints["served"])
            check_type(argname="argument storage", value=storage, expected_type=type_hints["storage"])
            check_type(argname="argument additional_printer_columns", value=additional_printer_columns, expected_type=type_hints["additional_printer_columns"])
            check_type(argname="argument deprecated", value=deprecated, expected_type=type_hints["deprecated"])
            check_type(argname="argument deprecation_warning", value=deprecation_warning, expected_type=type_hints["deprecation_warning"])
            check_type(argname="argument schema", value=schema, expected_type=type_hints["schema"])
            check_type(argname="argument subresources", value=subresources, expected_type=type_hints["subresources"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "served": served,
            "storage": storage,
        }
        if additional_printer_columns is not None:
            self._values["additional_printer_columns"] = additional_printer_columns
        if deprecated is not None:
            self._values["deprecated"] = deprecated
        if deprecation_warning is not None:
            self._values["deprecation_warning"] = deprecation_warning
        if schema is not None:
            self._values["schema"] = schema
        if subresources is not None:
            self._values["subresources"] = subresources

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the version name, e.g. “v1”, “v2beta1”, etc. The custom resources are served under this version at ``/apis/<group>/<version>/...`` if ``served`` is true.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def served(self) -> builtins.bool:
        '''served is a flag enabling/disabling this version from being served via REST APIs.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#served
        '''
        result = self._values.get("served")
        assert result is not None, "Required property 'served' is missing"
        return typing.cast(builtins.bool, result)

    @builtins.property
    def storage(self) -> builtins.bool:
        '''storage indicates this version should be used when persisting custom resources to storage.

        There must be exactly one version with storage=true.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#storage
        '''
        result = self._values.get("storage")
        assert result is not None, "Required property 'storage' is missing"
        return typing.cast(builtins.bool, result)

    @builtins.property
    def additional_printer_columns(
        self,
    ) -> typing.Optional[typing.List[CustomResourceColumnDefinition]]:
        '''additionalPrinterColumns specifies additional columns returned in Table output.

        See https://kubernetes.io/docs/reference/using-api/api-concepts/#receiving-resources-as-tables for details. If no columns are specified, a single column displaying the age of the custom resource is used.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#additionalPrinterColumns
        '''
        result = self._values.get("additional_printer_columns")
        return typing.cast(typing.Optional[typing.List[CustomResourceColumnDefinition]], result)

    @builtins.property
    def deprecated(self) -> typing.Optional[builtins.bool]:
        '''deprecated indicates this version of the custom resource API is deprecated.

        When set to true, API requests to this version receive a warning header in the server response. Defaults to false.

        :default: false.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#deprecated
        '''
        result = self._values.get("deprecated")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def deprecation_warning(self) -> typing.Optional[builtins.str]:
        '''deprecationWarning overrides the default warning returned to API clients.

        May only be set when ``deprecated`` is true. The default warning indicates this version is deprecated and recommends use of the newest served version of equal or greater stability, if one exists.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#deprecationWarning
        '''
        result = self._values.get("deprecation_warning")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def schema(self) -> typing.Optional["CustomResourceValidation"]:
        '''schema describes the schema used for validation, pruning, and defaulting of this version of the custom resource.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#schema
        '''
        result = self._values.get("schema")
        return typing.cast(typing.Optional["CustomResourceValidation"], result)

    @builtins.property
    def subresources(self) -> typing.Optional["CustomResourceSubresources"]:
        '''subresources specify what subresources this version of the defined custom resource have.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionVersion#subresources
        '''
        result = self._values.get("subresources")
        return typing.cast(typing.Optional["CustomResourceSubresources"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceDefinitionVersion(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceSubresourceScale",
    jsii_struct_bases=[],
    name_mapping={
        "spec_replicas_path": "specReplicasPath",
        "status_replicas_path": "statusReplicasPath",
        "label_selector_path": "labelSelectorPath",
    },
)
class CustomResourceSubresourceScale:
    def __init__(
        self,
        *,
        spec_replicas_path: builtins.str,
        status_replicas_path: builtins.str,
        label_selector_path: typing.Optional[builtins.str] = None,
    ) -> None:
        '''CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources.

        :param spec_replicas_path: specReplicasPath defines the JSON path inside of a custom resource that corresponds to Scale ``spec.replicas``. Only JSON paths without the array notation are allowed. Must be a JSON Path under ``.spec``. If there is no value under the given path in the custom resource, the ``/scale`` subresource will return an error on GET.
        :param status_replicas_path: statusReplicasPath defines the JSON path inside of a custom resource that corresponds to Scale ``status.replicas``. Only JSON paths without the array notation are allowed. Must be a JSON Path under ``.status``. If there is no value under the given path in the custom resource, the ``status.replicas`` value in the ``/scale`` subresource will default to 0.
        :param label_selector_path: labelSelectorPath defines the JSON path inside of a custom resource that corresponds to Scale ``status.selector``. Only JSON paths without the array notation are allowed. Must be a JSON Path under ``.status`` or ``.spec``. Must be set to work with HorizontalPodAutoscaler. The field pointed by this JSON path must be a string field (not a complex selector struct) which contains a serialized label selector in string form. More info: https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions#scale-subresource If there is no value under the given path in the custom resource, the ``status.selector`` value in the ``/scale`` subresource will default to the empty string.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresourceScale
        '''
        if __debug__:
            def stub(
                *,
                spec_replicas_path: builtins.str,
                status_replicas_path: builtins.str,
                label_selector_path: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec_replicas_path", value=spec_replicas_path, expected_type=type_hints["spec_replicas_path"])
            check_type(argname="argument status_replicas_path", value=status_replicas_path, expected_type=type_hints["status_replicas_path"])
            check_type(argname="argument label_selector_path", value=label_selector_path, expected_type=type_hints["label_selector_path"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec_replicas_path": spec_replicas_path,
            "status_replicas_path": status_replicas_path,
        }
        if label_selector_path is not None:
            self._values["label_selector_path"] = label_selector_path

    @builtins.property
    def spec_replicas_path(self) -> builtins.str:
        '''specReplicasPath defines the JSON path inside of a custom resource that corresponds to Scale ``spec.replicas``. Only JSON paths without the array notation are allowed. Must be a JSON Path under ``.spec``. If there is no value under the given path in the custom resource, the ``/scale`` subresource will return an error on GET.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresourceScale#specReplicasPath
        '''
        result = self._values.get("spec_replicas_path")
        assert result is not None, "Required property 'spec_replicas_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def status_replicas_path(self) -> builtins.str:
        '''statusReplicasPath defines the JSON path inside of a custom resource that corresponds to Scale ``status.replicas``. Only JSON paths without the array notation are allowed. Must be a JSON Path under ``.status``. If there is no value under the given path in the custom resource, the ``status.replicas`` value in the ``/scale`` subresource will default to 0.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresourceScale#statusReplicasPath
        '''
        result = self._values.get("status_replicas_path")
        assert result is not None, "Required property 'status_replicas_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def label_selector_path(self) -> typing.Optional[builtins.str]:
        '''labelSelectorPath defines the JSON path inside of a custom resource that corresponds to Scale ``status.selector``. Only JSON paths without the array notation are allowed. Must be a JSON Path under ``.status`` or ``.spec``. Must be set to work with HorizontalPodAutoscaler. The field pointed by this JSON path must be a string field (not a complex selector struct) which contains a serialized label selector in string form. More info: https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions#scale-subresource If there is no value under the given path in the custom resource, the ``status.selector`` value in the ``/scale`` subresource will default to the empty string.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresourceScale#labelSelectorPath
        '''
        result = self._values.get("label_selector_path")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceSubresourceScale(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceSubresources",
    jsii_struct_bases=[],
    name_mapping={"scale": "scale", "status": "status"},
)
class CustomResourceSubresources:
    def __init__(
        self,
        *,
        scale: typing.Optional[typing.Union[CustomResourceSubresourceScale, typing.Dict[str, typing.Any]]] = None,
        status: typing.Any = None,
    ) -> None:
        '''CustomResourceSubresources defines the status and scale subresources for CustomResources.

        :param scale: scale indicates the custom resource should serve a ``/scale`` subresource that returns an ``autoscaling/v1`` Scale object.
        :param status: status indicates the custom resource should serve a ``/status`` subresource. When enabled: 1. requests to the custom resource primary endpoint ignore changes to the ``status`` stanza of the object. 2. requests to the custom resource ``/status`` subresource ignore changes to anything other than the ``status`` stanza of the object.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresources
        '''
        if isinstance(scale, dict):
            scale = CustomResourceSubresourceScale(**scale)
        if __debug__:
            def stub(
                *,
                scale: typing.Optional[typing.Union[CustomResourceSubresourceScale, typing.Dict[str, typing.Any]]] = None,
                status: typing.Any = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scale", value=scale, expected_type=type_hints["scale"])
            check_type(argname="argument status", value=status, expected_type=type_hints["status"])
        self._values: typing.Dict[str, typing.Any] = {}
        if scale is not None:
            self._values["scale"] = scale
        if status is not None:
            self._values["status"] = status

    @builtins.property
    def scale(self) -> typing.Optional[CustomResourceSubresourceScale]:
        '''scale indicates the custom resource should serve a ``/scale`` subresource that returns an ``autoscaling/v1`` Scale object.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresources#scale
        '''
        result = self._values.get("scale")
        return typing.cast(typing.Optional[CustomResourceSubresourceScale], result)

    @builtins.property
    def status(self) -> typing.Any:
        '''status indicates the custom resource should serve a ``/status`` subresource.

        When enabled: 1. requests to the custom resource primary endpoint ignore changes to the ``status`` stanza of the object. 2. requests to the custom resource ``/status`` subresource ignore changes to anything other than the ``status`` stanza of the object.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceSubresources#status
        '''
        result = self._values.get("status")
        return typing.cast(typing.Any, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceSubresources(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.CustomResourceValidation",
    jsii_struct_bases=[],
    name_mapping={"open_apiv3_schema": "openApiv3Schema"},
)
class CustomResourceValidation:
    def __init__(
        self,
        *,
        open_apiv3_schema: typing.Optional[typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CustomResourceValidation is a list of validation methods for CustomResources.

        :param open_apiv3_schema: openAPIV3Schema is the OpenAPI v3 schema to use for validation and pruning.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceValidation
        '''
        if isinstance(open_apiv3_schema, dict):
            open_apiv3_schema = JsonSchemaProps(**open_apiv3_schema)
        if __debug__:
            def stub(
                *,
                open_apiv3_schema: typing.Optional[typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument open_apiv3_schema", value=open_apiv3_schema, expected_type=type_hints["open_apiv3_schema"])
        self._values: typing.Dict[str, typing.Any] = {}
        if open_apiv3_schema is not None:
            self._values["open_apiv3_schema"] = open_apiv3_schema

    @builtins.property
    def open_apiv3_schema(self) -> typing.Optional["JsonSchemaProps"]:
        '''openAPIV3Schema is the OpenAPI v3 schema to use for validation and pruning.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceValidation#openAPIV3Schema
        '''
        result = self._values.get("open_apiv3_schema")
        return typing.cast(typing.Optional["JsonSchemaProps"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomResourceValidation(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DaemonSetSpec",
    jsii_struct_bases=[],
    name_mapping={
        "selector": "selector",
        "template": "template",
        "min_ready_seconds": "minReadySeconds",
        "revision_history_limit": "revisionHistoryLimit",
        "update_strategy": "updateStrategy",
    },
)
class DaemonSetSpec:
    def __init__(
        self,
        *,
        selector: typing.Union["LabelSelector", typing.Dict[str, typing.Any]],
        template: typing.Union["PodTemplateSpec", typing.Dict[str, typing.Any]],
        min_ready_seconds: typing.Optional[jsii.Number] = None,
        revision_history_limit: typing.Optional[jsii.Number] = None,
        update_strategy: typing.Optional[typing.Union["DaemonSetUpdateStrategy", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''DaemonSetSpec is the specification of a daemon set.

        :param selector: A label query over pods that are managed by the daemon set. Must match in order to be controlled. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
        :param template: An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
        :param min_ready_seconds: The minimum number of seconds for which a newly created DaemonSet pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready). Default: 0 (pod will be considered available as soon as it is ready).
        :param revision_history_limit: The number of old history to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10. Default: 10.
        :param update_strategy: An update strategy to replace existing DaemonSet pods with new pods.

        :schema: io.k8s.api.apps.v1.DaemonSetSpec
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if isinstance(update_strategy, dict):
            update_strategy = DaemonSetUpdateStrategy(**update_strategy)
        if __debug__:
            def stub(
                *,
                selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
                template: typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]],
                min_ready_seconds: typing.Optional[jsii.Number] = None,
                revision_history_limit: typing.Optional[jsii.Number] = None,
                update_strategy: typing.Optional[typing.Union[DaemonSetUpdateStrategy, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
            check_type(argname="argument min_ready_seconds", value=min_ready_seconds, expected_type=type_hints["min_ready_seconds"])
            check_type(argname="argument revision_history_limit", value=revision_history_limit, expected_type=type_hints["revision_history_limit"])
            check_type(argname="argument update_strategy", value=update_strategy, expected_type=type_hints["update_strategy"])
        self._values: typing.Dict[str, typing.Any] = {
            "selector": selector,
            "template": template,
        }
        if min_ready_seconds is not None:
            self._values["min_ready_seconds"] = min_ready_seconds
        if revision_history_limit is not None:
            self._values["revision_history_limit"] = revision_history_limit
        if update_strategy is not None:
            self._values["update_strategy"] = update_strategy

    @builtins.property
    def selector(self) -> "LabelSelector":
        '''A label query over pods that are managed by the daemon set.

        Must match in order to be controlled. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

        :schema: io.k8s.api.apps.v1.DaemonSetSpec#selector
        '''
        result = self._values.get("selector")
        assert result is not None, "Required property 'selector' is missing"
        return typing.cast("LabelSelector", result)

    @builtins.property
    def template(self) -> "PodTemplateSpec":
        '''An object that describes the pod that will be created.

        The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template

        :schema: io.k8s.api.apps.v1.DaemonSetSpec#template
        '''
        result = self._values.get("template")
        assert result is not None, "Required property 'template' is missing"
        return typing.cast("PodTemplateSpec", result)

    @builtins.property
    def min_ready_seconds(self) -> typing.Optional[jsii.Number]:
        '''The minimum number of seconds for which a newly created DaemonSet pod should be ready without any of its container crashing, for it to be considered available.

        Defaults to 0 (pod will be considered available as soon as it is ready).

        :default: 0 (pod will be considered available as soon as it is ready).

        :schema: io.k8s.api.apps.v1.DaemonSetSpec#minReadySeconds
        '''
        result = self._values.get("min_ready_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def revision_history_limit(self) -> typing.Optional[jsii.Number]:
        '''The number of old history to retain to allow rollback.

        This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.

        :default: 10.

        :schema: io.k8s.api.apps.v1.DaemonSetSpec#revisionHistoryLimit
        '''
        result = self._values.get("revision_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def update_strategy(self) -> typing.Optional["DaemonSetUpdateStrategy"]:
        '''An update strategy to replace existing DaemonSet pods with new pods.

        :schema: io.k8s.api.apps.v1.DaemonSetSpec#updateStrategy
        '''
        result = self._values.get("update_strategy")
        return typing.cast(typing.Optional["DaemonSetUpdateStrategy"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DaemonSetSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DaemonSetUpdateStrategy",
    jsii_struct_bases=[],
    name_mapping={"rolling_update": "rollingUpdate", "type": "type"},
)
class DaemonSetUpdateStrategy:
    def __init__(
        self,
        *,
        rolling_update: typing.Optional[typing.Union["RollingUpdateDaemonSet", typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional["IoK8SApiAppsV1DaemonSetUpdateStrategyType"] = None,
    ) -> None:
        '''DaemonSetUpdateStrategy is a struct used to control the update strategy for a DaemonSet.

        :param rolling_update: Rolling update config params. Present only if type = "RollingUpdate".
        :param type: Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate. Possible enum values: - ``"OnDelete"`` Replace the old daemons only when it's killed - ``"RollingUpdate"`` Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other. Default: RollingUpdate.

        :schema: io.k8s.api.apps.v1.DaemonSetUpdateStrategy
        '''
        if isinstance(rolling_update, dict):
            rolling_update = RollingUpdateDaemonSet(**rolling_update)
        if __debug__:
            def stub(
                *,
                rolling_update: typing.Optional[typing.Union[RollingUpdateDaemonSet, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[IoK8SApiAppsV1DaemonSetUpdateStrategyType] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rolling_update", value=rolling_update, expected_type=type_hints["rolling_update"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {}
        if rolling_update is not None:
            self._values["rolling_update"] = rolling_update
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def rolling_update(self) -> typing.Optional["RollingUpdateDaemonSet"]:
        '''Rolling update config params.

        Present only if type = "RollingUpdate".

        :schema: io.k8s.api.apps.v1.DaemonSetUpdateStrategy#rollingUpdate
        '''
        result = self._values.get("rolling_update")
        return typing.cast(typing.Optional["RollingUpdateDaemonSet"], result)

    @builtins.property
    def type(self) -> typing.Optional["IoK8SApiAppsV1DaemonSetUpdateStrategyType"]:
        '''Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.

        Possible enum values:

        - ``"OnDelete"`` Replace the old daemons only when it's killed
        - ``"RollingUpdate"`` Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.

        :default: RollingUpdate.

        :schema: io.k8s.api.apps.v1.DaemonSetUpdateStrategy#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional["IoK8SApiAppsV1DaemonSetUpdateStrategyType"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DaemonSetUpdateStrategy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DeleteOptions",
    jsii_struct_bases=[],
    name_mapping={
        "api_version": "apiVersion",
        "dry_run": "dryRun",
        "grace_period_seconds": "gracePeriodSeconds",
        "kind": "kind",
        "orphan_dependents": "orphanDependents",
        "preconditions": "preconditions",
        "propagation_policy": "propagationPolicy",
    },
)
class DeleteOptions:
    def __init__(
        self,
        *,
        api_version: typing.Optional[builtins.str] = None,
        dry_run: typing.Optional[typing.Sequence[builtins.str]] = None,
        grace_period_seconds: typing.Optional[jsii.Number] = None,
        kind: typing.Optional["IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind"] = None,
        orphan_dependents: typing.Optional[builtins.bool] = None,
        preconditions: typing.Optional[typing.Union["Preconditions", typing.Dict[str, typing.Any]]] = None,
        propagation_policy: typing.Optional[builtins.str] = None,
    ) -> None:
        '''DeleteOptions may be provided when deleting an API object.

        :param api_version: 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
        :param dry_run: When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed
        :param grace_period_seconds: The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. Default: a per object value if not specified. zero means delete immediately.
        :param kind: 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
        :param orphan_dependents: Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.
        :param preconditions: Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned.
        :param propagation_policy: Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions
        '''
        if isinstance(preconditions, dict):
            preconditions = Preconditions(**preconditions)
        if __debug__:
            def stub(
                *,
                api_version: typing.Optional[builtins.str] = None,
                dry_run: typing.Optional[typing.Sequence[builtins.str]] = None,
                grace_period_seconds: typing.Optional[jsii.Number] = None,
                kind: typing.Optional[IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind] = None,
                orphan_dependents: typing.Optional[builtins.bool] = None,
                preconditions: typing.Optional[typing.Union[Preconditions, typing.Dict[str, typing.Any]]] = None,
                propagation_policy: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
            check_type(argname="argument dry_run", value=dry_run, expected_type=type_hints["dry_run"])
            check_type(argname="argument grace_period_seconds", value=grace_period_seconds, expected_type=type_hints["grace_period_seconds"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument orphan_dependents", value=orphan_dependents, expected_type=type_hints["orphan_dependents"])
            check_type(argname="argument preconditions", value=preconditions, expected_type=type_hints["preconditions"])
            check_type(argname="argument propagation_policy", value=propagation_policy, expected_type=type_hints["propagation_policy"])
        self._values: typing.Dict[str, typing.Any] = {}
        if api_version is not None:
            self._values["api_version"] = api_version
        if dry_run is not None:
            self._values["dry_run"] = dry_run
        if grace_period_seconds is not None:
            self._values["grace_period_seconds"] = grace_period_seconds
        if kind is not None:
            self._values["kind"] = kind
        if orphan_dependents is not None:
            self._values["orphan_dependents"] = orphan_dependents
        if preconditions is not None:
            self._values["preconditions"] = preconditions
        if propagation_policy is not None:
            self._values["propagation_policy"] = propagation_policy

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''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

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def dry_run(self) -> typing.Optional[typing.List[builtins.str]]:
        '''When present, indicates that modifications should not be persisted.

        An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#dryRun
        '''
        result = self._values.get("dry_run")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def grace_period_seconds(self) -> typing.Optional[jsii.Number]:
        '''The duration in seconds before the object should be deleted.

        Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.

        :default: a per object value if not specified. zero means delete immediately.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#gracePeriodSeconds
        '''
        result = self._values.get("grace_period_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def kind(
        self,
    ) -> typing.Optional["IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind"]:
        '''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

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#kind
        '''
        result = self._values.get("kind")
        return typing.cast(typing.Optional["IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind"], result)

    @builtins.property
    def orphan_dependents(self) -> typing.Optional[builtins.bool]:
        '''Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#orphanDependents
        '''
        result = self._values.get("orphan_dependents")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def preconditions(self) -> typing.Optional["Preconditions"]:
        '''Must be fulfilled before a deletion is carried out.

        If not possible, a 409 Conflict status will be returned.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#preconditions
        '''
        result = self._values.get("preconditions")
        return typing.cast(typing.Optional["Preconditions"], result)

    @builtins.property
    def propagation_policy(self) -> typing.Optional[builtins.str]:
        '''Whether and how garbage collection will be performed.

        Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions#propagationPolicy
        '''
        result = self._values.get("propagation_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DeleteOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DeploymentSpec",
    jsii_struct_bases=[],
    name_mapping={
        "selector": "selector",
        "template": "template",
        "min_ready_seconds": "minReadySeconds",
        "paused": "paused",
        "progress_deadline_seconds": "progressDeadlineSeconds",
        "replicas": "replicas",
        "revision_history_limit": "revisionHistoryLimit",
        "strategy": "strategy",
    },
)
class DeploymentSpec:
    def __init__(
        self,
        *,
        selector: typing.Union["LabelSelector", typing.Dict[str, typing.Any]],
        template: typing.Union["PodTemplateSpec", typing.Dict[str, typing.Any]],
        min_ready_seconds: typing.Optional[jsii.Number] = None,
        paused: typing.Optional[builtins.bool] = None,
        progress_deadline_seconds: typing.Optional[jsii.Number] = None,
        replicas: typing.Optional[jsii.Number] = None,
        revision_history_limit: typing.Optional[jsii.Number] = None,
        strategy: typing.Optional[typing.Union["DeploymentStrategy", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''DeploymentSpec is the specification of the desired behavior of the Deployment.

        :param selector: Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.
        :param template: Template describes the pods that will be created.
        :param min_ready_seconds: Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) Default: 0 (pod will be considered available as soon as it is ready)
        :param paused: Indicates that the deployment is paused.
        :param progress_deadline_seconds: The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s. Default: 600s.
        :param replicas: Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1. Default: 1.
        :param revision_history_limit: The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10. Default: 10.
        :param strategy: The deployment strategy to use to replace existing pods with new ones.

        :schema: io.k8s.api.apps.v1.DeploymentSpec
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if isinstance(strategy, dict):
            strategy = DeploymentStrategy(**strategy)
        if __debug__:
            def stub(
                *,
                selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
                template: typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]],
                min_ready_seconds: typing.Optional[jsii.Number] = None,
                paused: typing.Optional[builtins.bool] = None,
                progress_deadline_seconds: typing.Optional[jsii.Number] = None,
                replicas: typing.Optional[jsii.Number] = None,
                revision_history_limit: typing.Optional[jsii.Number] = None,
                strategy: typing.Optional[typing.Union[DeploymentStrategy, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
            check_type(argname="argument min_ready_seconds", value=min_ready_seconds, expected_type=type_hints["min_ready_seconds"])
            check_type(argname="argument paused", value=paused, expected_type=type_hints["paused"])
            check_type(argname="argument progress_deadline_seconds", value=progress_deadline_seconds, expected_type=type_hints["progress_deadline_seconds"])
            check_type(argname="argument replicas", value=replicas, expected_type=type_hints["replicas"])
            check_type(argname="argument revision_history_limit", value=revision_history_limit, expected_type=type_hints["revision_history_limit"])
            check_type(argname="argument strategy", value=strategy, expected_type=type_hints["strategy"])
        self._values: typing.Dict[str, typing.Any] = {
            "selector": selector,
            "template": template,
        }
        if min_ready_seconds is not None:
            self._values["min_ready_seconds"] = min_ready_seconds
        if paused is not None:
            self._values["paused"] = paused
        if progress_deadline_seconds is not None:
            self._values["progress_deadline_seconds"] = progress_deadline_seconds
        if replicas is not None:
            self._values["replicas"] = replicas
        if revision_history_limit is not None:
            self._values["revision_history_limit"] = revision_history_limit
        if strategy is not None:
            self._values["strategy"] = strategy

    @builtins.property
    def selector(self) -> "LabelSelector":
        '''Label selector for pods.

        Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#selector
        '''
        result = self._values.get("selector")
        assert result is not None, "Required property 'selector' is missing"
        return typing.cast("LabelSelector", result)

    @builtins.property
    def template(self) -> "PodTemplateSpec":
        '''Template describes the pods that will be created.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#template
        '''
        result = self._values.get("template")
        assert result is not None, "Required property 'template' is missing"
        return typing.cast("PodTemplateSpec", result)

    @builtins.property
    def min_ready_seconds(self) -> typing.Optional[jsii.Number]:
        '''Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available.

        Defaults to 0 (pod will be considered available as soon as it is ready)

        :default: 0 (pod will be considered available as soon as it is ready)

        :schema: io.k8s.api.apps.v1.DeploymentSpec#minReadySeconds
        '''
        result = self._values.get("min_ready_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def paused(self) -> typing.Optional[builtins.bool]:
        '''Indicates that the deployment is paused.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#paused
        '''
        result = self._values.get("paused")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def progress_deadline_seconds(self) -> typing.Optional[jsii.Number]:
        '''The maximum time in seconds for a deployment to make progress before it is considered to be failed.

        The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s.

        :default: 600s.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#progressDeadlineSeconds
        '''
        result = self._values.get("progress_deadline_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def replicas(self) -> typing.Optional[jsii.Number]:
        '''Number of desired pods.

        This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.

        :default: 1.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#replicas
        '''
        result = self._values.get("replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def revision_history_limit(self) -> typing.Optional[jsii.Number]:
        '''The number of old ReplicaSets to retain to allow rollback.

        This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.

        :default: 10.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#revisionHistoryLimit
        '''
        result = self._values.get("revision_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def strategy(self) -> typing.Optional["DeploymentStrategy"]:
        '''The deployment strategy to use to replace existing pods with new ones.

        :schema: io.k8s.api.apps.v1.DeploymentSpec#strategy
        '''
        result = self._values.get("strategy")
        return typing.cast(typing.Optional["DeploymentStrategy"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DeploymentSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DeploymentStrategy",
    jsii_struct_bases=[],
    name_mapping={"rolling_update": "rollingUpdate", "type": "type"},
)
class DeploymentStrategy:
    def __init__(
        self,
        *,
        rolling_update: typing.Optional[typing.Union["RollingUpdateDeployment", typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional["IoK8SApiAppsV1DeploymentStrategyType"] = None,
    ) -> None:
        '''DeploymentStrategy describes how to replace existing pods with new ones.

        :param rolling_update: Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate.
        :param type: Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. Possible enum values: - ``"Recreate"`` Kill all existing pods before creating new ones. - ``"RollingUpdate"`` Replace the old ReplicaSets by new one using rolling update i.e gradually scale down the old ReplicaSets and scale up the new one. Default: RollingUpdate.

        :schema: io.k8s.api.apps.v1.DeploymentStrategy
        '''
        if isinstance(rolling_update, dict):
            rolling_update = RollingUpdateDeployment(**rolling_update)
        if __debug__:
            def stub(
                *,
                rolling_update: typing.Optional[typing.Union[RollingUpdateDeployment, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[IoK8SApiAppsV1DeploymentStrategyType] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rolling_update", value=rolling_update, expected_type=type_hints["rolling_update"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {}
        if rolling_update is not None:
            self._values["rolling_update"] = rolling_update
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def rolling_update(self) -> typing.Optional["RollingUpdateDeployment"]:
        '''Rolling update config params.

        Present only if DeploymentStrategyType = RollingUpdate.

        :schema: io.k8s.api.apps.v1.DeploymentStrategy#rollingUpdate
        '''
        result = self._values.get("rolling_update")
        return typing.cast(typing.Optional["RollingUpdateDeployment"], result)

    @builtins.property
    def type(self) -> typing.Optional["IoK8SApiAppsV1DeploymentStrategyType"]:
        '''Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.

        Possible enum values:

        - ``"Recreate"`` Kill all existing pods before creating new ones.
        - ``"RollingUpdate"`` Replace the old ReplicaSets by new one using rolling update i.e gradually scale down the old ReplicaSets and scale up the new one.

        :default: RollingUpdate.

        :schema: io.k8s.api.apps.v1.DeploymentStrategy#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional["IoK8SApiAppsV1DeploymentStrategyType"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DeploymentStrategy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DownwardApiProjection",
    jsii_struct_bases=[],
    name_mapping={"items": "items"},
)
class DownwardApiProjection:
    def __init__(
        self,
        *,
        items: typing.Optional[typing.Sequence[typing.Union["DownwardApiVolumeFile", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Represents downward API info for projecting into a projected volume.

        Note that this is identical to a downwardAPI volume source without the default mode.

        :param items: Items is a list of DownwardAPIVolume file.

        :schema: io.k8s.api.core.v1.DownwardAPIProjection
        '''
        if __debug__:
            def stub(
                *,
                items: typing.Optional[typing.Sequence[typing.Union[DownwardApiVolumeFile, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
        self._values: typing.Dict[str, typing.Any] = {}
        if items is not None:
            self._values["items"] = items

    @builtins.property
    def items(self) -> typing.Optional[typing.List["DownwardApiVolumeFile"]]:
        '''Items is a list of DownwardAPIVolume file.

        :schema: io.k8s.api.core.v1.DownwardAPIProjection#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Optional[typing.List["DownwardApiVolumeFile"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DownwardApiProjection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DownwardApiVolumeFile",
    jsii_struct_bases=[],
    name_mapping={
        "path": "path",
        "field_ref": "fieldRef",
        "mode": "mode",
        "resource_field_ref": "resourceFieldRef",
    },
)
class DownwardApiVolumeFile:
    def __init__(
        self,
        *,
        path: builtins.str,
        field_ref: typing.Optional[typing.Union["ObjectFieldSelector", typing.Dict[str, typing.Any]]] = None,
        mode: typing.Optional[jsii.Number] = None,
        resource_field_ref: typing.Optional[typing.Union["ResourceFieldSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''DownwardAPIVolumeFile represents information to create the file containing the pod field.

        :param path: Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'
        :param field_ref: Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
        :param mode: Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.
        :param resource_field_ref: Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeFile
        '''
        if isinstance(field_ref, dict):
            field_ref = ObjectFieldSelector(**field_ref)
        if isinstance(resource_field_ref, dict):
            resource_field_ref = ResourceFieldSelector(**resource_field_ref)
        if __debug__:
            def stub(
                *,
                path: builtins.str,
                field_ref: typing.Optional[typing.Union[ObjectFieldSelector, typing.Dict[str, typing.Any]]] = None,
                mode: typing.Optional[jsii.Number] = None,
                resource_field_ref: typing.Optional[typing.Union[ResourceFieldSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument field_ref", value=field_ref, expected_type=type_hints["field_ref"])
            check_type(argname="argument mode", value=mode, expected_type=type_hints["mode"])
            check_type(argname="argument resource_field_ref", value=resource_field_ref, expected_type=type_hints["resource_field_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "path": path,
        }
        if field_ref is not None:
            self._values["field_ref"] = field_ref
        if mode is not None:
            self._values["mode"] = mode
        if resource_field_ref is not None:
            self._values["resource_field_ref"] = resource_field_ref

    @builtins.property
    def path(self) -> builtins.str:
        '''Required: Path is  the relative path name of the file to be created.

        Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeFile#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def field_ref(self) -> typing.Optional["ObjectFieldSelector"]:
        '''Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeFile#fieldRef
        '''
        result = self._values.get("field_ref")
        return typing.cast(typing.Optional["ObjectFieldSelector"], result)

    @builtins.property
    def mode(self) -> typing.Optional[jsii.Number]:
        '''Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.

        YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeFile#mode
        '''
        result = self._values.get("mode")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def resource_field_ref(self) -> typing.Optional["ResourceFieldSelector"]:
        '''Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeFile#resourceFieldRef
        '''
        result = self._values.get("resource_field_ref")
        return typing.cast(typing.Optional["ResourceFieldSelector"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DownwardApiVolumeFile(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.DownwardApiVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"default_mode": "defaultMode", "items": "items"},
)
class DownwardApiVolumeSource:
    def __init__(
        self,
        *,
        default_mode: typing.Optional[jsii.Number] = None,
        items: typing.Optional[typing.Sequence[typing.Union[DownwardApiVolumeFile, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''DownwardAPIVolumeSource represents a volume containing downward API info.

        Downward API volumes support ownership management and SELinux relabeling.

        :param default_mode: Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. Default: 644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.
        :param items: Items is a list of downward API volume file.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                default_mode: typing.Optional[jsii.Number] = None,
                items: typing.Optional[typing.Sequence[typing.Union[DownwardApiVolumeFile, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument default_mode", value=default_mode, expected_type=type_hints["default_mode"])
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
        self._values: typing.Dict[str, typing.Any] = {}
        if default_mode is not None:
            self._values["default_mode"] = default_mode
        if items is not None:
            self._values["items"] = items

    @builtins.property
    def default_mode(self) -> typing.Optional[jsii.Number]:
        '''Optional: mode bits to use on created files by default.

        Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :default: 644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeSource#defaultMode
        '''
        result = self._values.get("default_mode")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def items(self) -> typing.Optional[typing.List[DownwardApiVolumeFile]]:
        '''Items is a list of downward API volume file.

        :schema: io.k8s.api.core.v1.DownwardAPIVolumeSource#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Optional[typing.List[DownwardApiVolumeFile]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DownwardApiVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EmptyDirVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"medium": "medium", "size_limit": "sizeLimit"},
)
class EmptyDirVolumeSource:
    def __init__(
        self,
        *,
        medium: typing.Optional[builtins.str] = None,
        size_limit: typing.Optional["Quantity"] = None,
    ) -> None:
        '''Represents an empty directory for a pod.

        Empty directory volumes support ownership management and SELinux relabeling.

        :param medium: What type of storage medium should back this directory. The default is "" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
        :param size_limit: Total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir

        :schema: io.k8s.api.core.v1.EmptyDirVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                medium: typing.Optional[builtins.str] = None,
                size_limit: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument medium", value=medium, expected_type=type_hints["medium"])
            check_type(argname="argument size_limit", value=size_limit, expected_type=type_hints["size_limit"])
        self._values: typing.Dict[str, typing.Any] = {}
        if medium is not None:
            self._values["medium"] = medium
        if size_limit is not None:
            self._values["size_limit"] = size_limit

    @builtins.property
    def medium(self) -> typing.Optional[builtins.str]:
        '''What type of storage medium should back this directory.

        The default is "" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

        :schema: io.k8s.api.core.v1.EmptyDirVolumeSource#medium
        '''
        result = self._values.get("medium")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def size_limit(self) -> typing.Optional["Quantity"]:
        '''Total amount of local storage required for this EmptyDir volume.

        The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir

        :schema: io.k8s.api.core.v1.EmptyDirVolumeSource#sizeLimit
        '''
        result = self._values.get("size_limit")
        return typing.cast(typing.Optional["Quantity"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EmptyDirVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Endpoint",
    jsii_struct_bases=[],
    name_mapping={
        "addresses": "addresses",
        "conditions": "conditions",
        "deprecated_topology": "deprecatedTopology",
        "hints": "hints",
        "hostname": "hostname",
        "node_name": "nodeName",
        "target_ref": "targetRef",
        "zone": "zone",
    },
)
class Endpoint:
    def __init__(
        self,
        *,
        addresses: typing.Sequence[builtins.str],
        conditions: typing.Optional[typing.Union["EndpointConditions", typing.Dict[str, typing.Any]]] = None,
        deprecated_topology: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        hints: typing.Optional[typing.Union["EndpointHints", typing.Dict[str, typing.Any]]] = None,
        hostname: typing.Optional[builtins.str] = None,
        node_name: typing.Optional[builtins.str] = None,
        target_ref: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        zone: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Endpoint represents a single logical "backend" implementing a service.

        :param addresses: addresses of this endpoint. The contents of this field are interpreted according to the corresponding EndpointSlice addressType field. Consumers must handle different types of addresses in the context of their own capabilities. This must contain at least one address but no more than 100.
        :param conditions: conditions contains information about the current status of the endpoint.
        :param deprecated_topology: deprecatedTopology contains topology information part of the v1beta1 API. This field is deprecated, and will be removed when the v1beta1 API is removed (no sooner than kubernetes v1.24). While this field can hold values, it is not writable through the v1 API, and any attempts to write to it will be silently ignored. Topology information can be found in the zone and nodeName fields instead.
        :param hints: hints contains information associated with how an endpoint should be consumed.
        :param hostname: hostname of this endpoint. This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.
        :param node_name: nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node. This field can be enabled with the EndpointSliceNodeName feature gate.
        :param target_ref: targetRef is a reference to a Kubernetes object that represents this endpoint.
        :param zone: zone is the name of the Zone this endpoint exists in.

        :schema: io.k8s.api.discovery.v1.Endpoint
        '''
        if isinstance(conditions, dict):
            conditions = EndpointConditions(**conditions)
        if isinstance(hints, dict):
            hints = EndpointHints(**hints)
        if isinstance(target_ref, dict):
            target_ref = ObjectReference(**target_ref)
        if __debug__:
            def stub(
                *,
                addresses: typing.Sequence[builtins.str],
                conditions: typing.Optional[typing.Union[EndpointConditions, typing.Dict[str, typing.Any]]] = None,
                deprecated_topology: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                hints: typing.Optional[typing.Union[EndpointHints, typing.Dict[str, typing.Any]]] = None,
                hostname: typing.Optional[builtins.str] = None,
                node_name: typing.Optional[builtins.str] = None,
                target_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                zone: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument addresses", value=addresses, expected_type=type_hints["addresses"])
            check_type(argname="argument conditions", value=conditions, expected_type=type_hints["conditions"])
            check_type(argname="argument deprecated_topology", value=deprecated_topology, expected_type=type_hints["deprecated_topology"])
            check_type(argname="argument hints", value=hints, expected_type=type_hints["hints"])
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument node_name", value=node_name, expected_type=type_hints["node_name"])
            check_type(argname="argument target_ref", value=target_ref, expected_type=type_hints["target_ref"])
            check_type(argname="argument zone", value=zone, expected_type=type_hints["zone"])
        self._values: typing.Dict[str, typing.Any] = {
            "addresses": addresses,
        }
        if conditions is not None:
            self._values["conditions"] = conditions
        if deprecated_topology is not None:
            self._values["deprecated_topology"] = deprecated_topology
        if hints is not None:
            self._values["hints"] = hints
        if hostname is not None:
            self._values["hostname"] = hostname
        if node_name is not None:
            self._values["node_name"] = node_name
        if target_ref is not None:
            self._values["target_ref"] = target_ref
        if zone is not None:
            self._values["zone"] = zone

    @builtins.property
    def addresses(self) -> typing.List[builtins.str]:
        '''addresses of this endpoint.

        The contents of this field are interpreted according to the corresponding EndpointSlice addressType field. Consumers must handle different types of addresses in the context of their own capabilities. This must contain at least one address but no more than 100.

        :schema: io.k8s.api.discovery.v1.Endpoint#addresses
        '''
        result = self._values.get("addresses")
        assert result is not None, "Required property 'addresses' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def conditions(self) -> typing.Optional["EndpointConditions"]:
        '''conditions contains information about the current status of the endpoint.

        :schema: io.k8s.api.discovery.v1.Endpoint#conditions
        '''
        result = self._values.get("conditions")
        return typing.cast(typing.Optional["EndpointConditions"], result)

    @builtins.property
    def deprecated_topology(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''deprecatedTopology contains topology information part of the v1beta1 API.

        This field is deprecated, and will be removed when the v1beta1 API is removed (no sooner than kubernetes v1.24).  While this field can hold values, it is not writable through the v1 API, and any attempts to write to it will be silently ignored. Topology information can be found in the zone and nodeName fields instead.

        :schema: io.k8s.api.discovery.v1.Endpoint#deprecatedTopology
        '''
        result = self._values.get("deprecated_topology")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def hints(self) -> typing.Optional["EndpointHints"]:
        '''hints contains information associated with how an endpoint should be consumed.

        :schema: io.k8s.api.discovery.v1.Endpoint#hints
        '''
        result = self._values.get("hints")
        return typing.cast(typing.Optional["EndpointHints"], result)

    @builtins.property
    def hostname(self) -> typing.Optional[builtins.str]:
        '''hostname of this endpoint.

        This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.

        :schema: io.k8s.api.discovery.v1.Endpoint#hostname
        '''
        result = self._values.get("hostname")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_name(self) -> typing.Optional[builtins.str]:
        '''nodeName represents the name of the Node hosting this endpoint.

        This can be used to determine endpoints local to a Node. This field can be enabled with the EndpointSliceNodeName feature gate.

        :schema: io.k8s.api.discovery.v1.Endpoint#nodeName
        '''
        result = self._values.get("node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def target_ref(self) -> typing.Optional["ObjectReference"]:
        '''targetRef is a reference to a Kubernetes object that represents this endpoint.

        :schema: io.k8s.api.discovery.v1.Endpoint#targetRef
        '''
        result = self._values.get("target_ref")
        return typing.cast(typing.Optional["ObjectReference"], result)

    @builtins.property
    def zone(self) -> typing.Optional[builtins.str]:
        '''zone is the name of the Zone this endpoint exists in.

        :schema: io.k8s.api.discovery.v1.Endpoint#zone
        '''
        result = self._values.get("zone")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Endpoint(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointAddress",
    jsii_struct_bases=[],
    name_mapping={
        "ip": "ip",
        "hostname": "hostname",
        "node_name": "nodeName",
        "target_ref": "targetRef",
    },
)
class EndpointAddress:
    def __init__(
        self,
        *,
        ip: builtins.str,
        hostname: typing.Optional[builtins.str] = None,
        node_name: typing.Optional[builtins.str] = None,
        target_ref: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EndpointAddress is a tuple that describes single IP address.

        :param ip: The IP of this endpoint. May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast ((224.0.0.0/24). IPv6 is also accepted but not fully supported on all platforms. Also, certain kubernetes components, like kube-proxy, are not IPv6 ready.
        :param hostname: The Hostname of this endpoint.
        :param node_name: Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.
        :param target_ref: Reference to object providing the endpoint.

        :schema: io.k8s.api.core.v1.EndpointAddress
        '''
        if isinstance(target_ref, dict):
            target_ref = ObjectReference(**target_ref)
        if __debug__:
            def stub(
                *,
                ip: builtins.str,
                hostname: typing.Optional[builtins.str] = None,
                node_name: typing.Optional[builtins.str] = None,
                target_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ip", value=ip, expected_type=type_hints["ip"])
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument node_name", value=node_name, expected_type=type_hints["node_name"])
            check_type(argname="argument target_ref", value=target_ref, expected_type=type_hints["target_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "ip": ip,
        }
        if hostname is not None:
            self._values["hostname"] = hostname
        if node_name is not None:
            self._values["node_name"] = node_name
        if target_ref is not None:
            self._values["target_ref"] = target_ref

    @builtins.property
    def ip(self) -> builtins.str:
        '''The IP of this endpoint.

        May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast ((224.0.0.0/24). IPv6 is also accepted but not fully supported on all platforms. Also, certain kubernetes components, like kube-proxy, are not IPv6 ready.

        :schema: io.k8s.api.core.v1.EndpointAddress#ip
        '''
        result = self._values.get("ip")
        assert result is not None, "Required property 'ip' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def hostname(self) -> typing.Optional[builtins.str]:
        '''The Hostname of this endpoint.

        :schema: io.k8s.api.core.v1.EndpointAddress#hostname
        '''
        result = self._values.get("hostname")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_name(self) -> typing.Optional[builtins.str]:
        '''Optional: Node hosting this endpoint.

        This can be used to determine endpoints local to a node.

        :schema: io.k8s.api.core.v1.EndpointAddress#nodeName
        '''
        result = self._values.get("node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def target_ref(self) -> typing.Optional["ObjectReference"]:
        '''Reference to object providing the endpoint.

        :schema: io.k8s.api.core.v1.EndpointAddress#targetRef
        '''
        result = self._values.get("target_ref")
        return typing.cast(typing.Optional["ObjectReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointAddress(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointConditions",
    jsii_struct_bases=[],
    name_mapping={
        "ready": "ready",
        "serving": "serving",
        "terminating": "terminating",
    },
)
class EndpointConditions:
    def __init__(
        self,
        *,
        ready: typing.Optional[builtins.bool] = None,
        serving: typing.Optional[builtins.bool] = None,
        terminating: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''EndpointConditions represents the current condition of an endpoint.

        :param ready: ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be "true" for terminating endpoints.
        :param serving: serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.
        :param terminating: terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.

        :schema: io.k8s.api.discovery.v1.EndpointConditions
        '''
        if __debug__:
            def stub(
                *,
                ready: typing.Optional[builtins.bool] = None,
                serving: typing.Optional[builtins.bool] = None,
                terminating: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ready", value=ready, expected_type=type_hints["ready"])
            check_type(argname="argument serving", value=serving, expected_type=type_hints["serving"])
            check_type(argname="argument terminating", value=terminating, expected_type=type_hints["terminating"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ready is not None:
            self._values["ready"] = ready
        if serving is not None:
            self._values["serving"] = serving
        if terminating is not None:
            self._values["terminating"] = terminating

    @builtins.property
    def ready(self) -> typing.Optional[builtins.bool]:
        '''ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint.

        A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be "true" for terminating endpoints.

        :schema: io.k8s.api.discovery.v1.EndpointConditions#ready
        '''
        result = self._values.get("ready")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def serving(self) -> typing.Optional[builtins.bool]:
        '''serving is identical to ready except that it is set regardless of the terminating state of endpoints.

        This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.

        :schema: io.k8s.api.discovery.v1.EndpointConditions#serving
        '''
        result = self._values.get("serving")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def terminating(self) -> typing.Optional[builtins.bool]:
        '''terminating indicates that this endpoint is terminating.

        A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.

        :schema: io.k8s.api.discovery.v1.EndpointConditions#terminating
        '''
        result = self._values.get("terminating")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointConditions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointConditionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "ready": "ready",
        "serving": "serving",
        "terminating": "terminating",
    },
)
class EndpointConditionsV1Beta1:
    def __init__(
        self,
        *,
        ready: typing.Optional[builtins.bool] = None,
        serving: typing.Optional[builtins.bool] = None,
        terminating: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''EndpointConditions represents the current condition of an endpoint.

        :param ready: ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be "true" for terminating endpoints.
        :param serving: serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.
        :param terminating: terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.

        :schema: io.k8s.api.discovery.v1beta1.EndpointConditions
        '''
        if __debug__:
            def stub(
                *,
                ready: typing.Optional[builtins.bool] = None,
                serving: typing.Optional[builtins.bool] = None,
                terminating: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ready", value=ready, expected_type=type_hints["ready"])
            check_type(argname="argument serving", value=serving, expected_type=type_hints["serving"])
            check_type(argname="argument terminating", value=terminating, expected_type=type_hints["terminating"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ready is not None:
            self._values["ready"] = ready
        if serving is not None:
            self._values["serving"] = serving
        if terminating is not None:
            self._values["terminating"] = terminating

    @builtins.property
    def ready(self) -> typing.Optional[builtins.bool]:
        '''ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint.

        A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be "true" for terminating endpoints.

        :schema: io.k8s.api.discovery.v1beta1.EndpointConditions#ready
        '''
        result = self._values.get("ready")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def serving(self) -> typing.Optional[builtins.bool]:
        '''serving is identical to ready except that it is set regardless of the terminating state of endpoints.

        This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.

        :schema: io.k8s.api.discovery.v1beta1.EndpointConditions#serving
        '''
        result = self._values.get("serving")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def terminating(self) -> typing.Optional[builtins.bool]:
        '''terminating indicates that this endpoint is terminating.

        A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.

        :schema: io.k8s.api.discovery.v1beta1.EndpointConditions#terminating
        '''
        result = self._values.get("terminating")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointConditionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointHints",
    jsii_struct_bases=[],
    name_mapping={"for_zones": "forZones"},
)
class EndpointHints:
    def __init__(
        self,
        *,
        for_zones: typing.Optional[typing.Sequence[typing.Union["ForZone", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''EndpointHints provides hints describing how an endpoint should be consumed.

        :param for_zones: forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing.

        :schema: io.k8s.api.discovery.v1.EndpointHints
        '''
        if __debug__:
            def stub(
                *,
                for_zones: typing.Optional[typing.Sequence[typing.Union[ForZone, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument for_zones", value=for_zones, expected_type=type_hints["for_zones"])
        self._values: typing.Dict[str, typing.Any] = {}
        if for_zones is not None:
            self._values["for_zones"] = for_zones

    @builtins.property
    def for_zones(self) -> typing.Optional[typing.List["ForZone"]]:
        '''forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing.

        :schema: io.k8s.api.discovery.v1.EndpointHints#forZones
        '''
        result = self._values.get("for_zones")
        return typing.cast(typing.Optional[typing.List["ForZone"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointHints(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointHintsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"for_zones": "forZones"},
)
class EndpointHintsV1Beta1:
    def __init__(
        self,
        *,
        for_zones: typing.Optional[typing.Sequence[typing.Union["ForZoneV1Beta1", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''EndpointHints provides hints describing how an endpoint should be consumed.

        :param for_zones: forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing. May contain a maximum of 8 entries.

        :schema: io.k8s.api.discovery.v1beta1.EndpointHints
        '''
        if __debug__:
            def stub(
                *,
                for_zones: typing.Optional[typing.Sequence[typing.Union[ForZoneV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument for_zones", value=for_zones, expected_type=type_hints["for_zones"])
        self._values: typing.Dict[str, typing.Any] = {}
        if for_zones is not None:
            self._values["for_zones"] = for_zones

    @builtins.property
    def for_zones(self) -> typing.Optional[typing.List["ForZoneV1Beta1"]]:
        '''forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing.

        May contain a maximum of 8 entries.

        :schema: io.k8s.api.discovery.v1beta1.EndpointHints#forZones
        '''
        result = self._values.get("for_zones")
        return typing.cast(typing.Optional[typing.List["ForZoneV1Beta1"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointHintsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointPort",
    jsii_struct_bases=[],
    name_mapping={
        "port": "port",
        "app_protocol": "appProtocol",
        "name": "name",
        "protocol": "protocol",
    },
)
class EndpointPort:
    def __init__(
        self,
        *,
        port: jsii.Number,
        app_protocol: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        protocol: typing.Optional["IoK8SApiCoreV1EndpointPortProtocol"] = None,
    ) -> None:
        '''EndpointPort is a tuple that describes a single port.

        :param port: The port number of the endpoint.
        :param app_protocol: The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.
        :param name: The name of this port. This must match the 'name' field in the corresponding ServicePort. Must be a DNS_LABEL. Optional only if one port is defined.
        :param protocol: The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP. Possible enum values: - ``"SCTP"`` is the SCTP protocol. - ``"TCP"`` is the TCP protocol. - ``"UDP"`` is the UDP protocol. Default: TCP.

        :schema: io.k8s.api.core.v1.EndpointPort
        '''
        if __debug__:
            def stub(
                *,
                port: jsii.Number,
                app_protocol: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                protocol: typing.Optional[IoK8SApiCoreV1EndpointPortProtocol] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument app_protocol", value=app_protocol, expected_type=type_hints["app_protocol"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
        self._values: typing.Dict[str, typing.Any] = {
            "port": port,
        }
        if app_protocol is not None:
            self._values["app_protocol"] = app_protocol
        if name is not None:
            self._values["name"] = name
        if protocol is not None:
            self._values["protocol"] = protocol

    @builtins.property
    def port(self) -> jsii.Number:
        '''The port number of the endpoint.

        :schema: io.k8s.api.core.v1.EndpointPort#port
        '''
        result = self._values.get("port")
        assert result is not None, "Required property 'port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def app_protocol(self) -> typing.Optional[builtins.str]:
        '''The application protocol for this port.

        This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.

        :schema: io.k8s.api.core.v1.EndpointPort#appProtocol
        '''
        result = self._values.get("app_protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''The name of this port.

        This must match the 'name' field in the corresponding ServicePort. Must be a DNS_LABEL. Optional only if one port is defined.

        :schema: io.k8s.api.core.v1.EndpointPort#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def protocol(self) -> typing.Optional["IoK8SApiCoreV1EndpointPortProtocol"]:
        '''The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.

        Possible enum values:

        - ``"SCTP"`` is the SCTP protocol.
        - ``"TCP"`` is the TCP protocol.
        - ``"UDP"`` is the UDP protocol.

        :default: TCP.

        :schema: io.k8s.api.core.v1.EndpointPort#protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional["IoK8SApiCoreV1EndpointPortProtocol"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointPort(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointPortV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "app_protocol": "appProtocol",
        "name": "name",
        "port": "port",
        "protocol": "protocol",
    },
)
class EndpointPortV1Beta1:
    def __init__(
        self,
        *,
        app_protocol: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        port: typing.Optional[jsii.Number] = None,
        protocol: typing.Optional[builtins.str] = None,
    ) -> None:
        '''EndpointPort represents a Port used by an EndpointSlice.

        :param app_protocol: The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.
        :param name: The name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string. Default: empty string.
        :param port: The port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.
        :param protocol: The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP. Default: TCP.

        :schema: io.k8s.api.discovery.v1beta1.EndpointPort
        '''
        if __debug__:
            def stub(
                *,
                app_protocol: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                port: typing.Optional[jsii.Number] = None,
                protocol: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument app_protocol", value=app_protocol, expected_type=type_hints["app_protocol"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
        self._values: typing.Dict[str, typing.Any] = {}
        if app_protocol is not None:
            self._values["app_protocol"] = app_protocol
        if name is not None:
            self._values["name"] = name
        if port is not None:
            self._values["port"] = port
        if protocol is not None:
            self._values["protocol"] = protocol

    @builtins.property
    def app_protocol(self) -> typing.Optional[builtins.str]:
        '''The application protocol for this port.

        This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.

        :schema: io.k8s.api.discovery.v1beta1.EndpointPort#appProtocol
        '''
        result = self._values.get("app_protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''The name of this port.

        All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string.

        :default: empty string.

        :schema: io.k8s.api.discovery.v1beta1.EndpointPort#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''The port number of the endpoint.

        If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.

        :schema: io.k8s.api.discovery.v1beta1.EndpointPort#port
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def protocol(self) -> typing.Optional[builtins.str]:
        '''The IP protocol for this port.

        Must be UDP, TCP, or SCTP. Default is TCP.

        :default: TCP.

        :schema: io.k8s.api.discovery.v1beta1.EndpointPort#protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointPortV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointSubset",
    jsii_struct_bases=[],
    name_mapping={
        "addresses": "addresses",
        "not_ready_addresses": "notReadyAddresses",
        "ports": "ports",
    },
)
class EndpointSubset:
    def __init__(
        self,
        *,
        addresses: typing.Optional[typing.Sequence[typing.Union[EndpointAddress, typing.Dict[str, typing.Any]]]] = None,
        not_ready_addresses: typing.Optional[typing.Sequence[typing.Union[EndpointAddress, typing.Dict[str, typing.Any]]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''EndpointSubset is a group of addresses with a common set of ports.

        The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:
        {
        Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
        Ports:     [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
        }
        The resulting set of endpoints can be viewed as:
        a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],
        b: [ 10.10.1.1:309, 10.10.2.2:309 ]

        :param addresses: IP addresses which offer the related ports that are marked as ready. These endpoints should be considered safe for load balancers and clients to utilize.
        :param not_ready_addresses: IP addresses which offer the related ports but are not currently marked as ready because they have not yet finished starting, have recently failed a readiness check, or have recently failed a liveness check.
        :param ports: Port numbers available on the related IP addresses.

        :schema: io.k8s.api.core.v1.EndpointSubset
        '''
        if __debug__:
            def stub(
                *,
                addresses: typing.Optional[typing.Sequence[typing.Union[EndpointAddress, typing.Dict[str, typing.Any]]]] = None,
                not_ready_addresses: typing.Optional[typing.Sequence[typing.Union[EndpointAddress, typing.Dict[str, typing.Any]]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument addresses", value=addresses, expected_type=type_hints["addresses"])
            check_type(argname="argument not_ready_addresses", value=not_ready_addresses, expected_type=type_hints["not_ready_addresses"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
        self._values: typing.Dict[str, typing.Any] = {}
        if addresses is not None:
            self._values["addresses"] = addresses
        if not_ready_addresses is not None:
            self._values["not_ready_addresses"] = not_ready_addresses
        if ports is not None:
            self._values["ports"] = ports

    @builtins.property
    def addresses(self) -> typing.Optional[typing.List[EndpointAddress]]:
        '''IP addresses which offer the related ports that are marked as ready.

        These endpoints should be considered safe for load balancers and clients to utilize.

        :schema: io.k8s.api.core.v1.EndpointSubset#addresses
        '''
        result = self._values.get("addresses")
        return typing.cast(typing.Optional[typing.List[EndpointAddress]], result)

    @builtins.property
    def not_ready_addresses(self) -> typing.Optional[typing.List[EndpointAddress]]:
        '''IP addresses which offer the related ports but are not currently marked as ready because they have not yet finished starting, have recently failed a readiness check, or have recently failed a liveness check.

        :schema: io.k8s.api.core.v1.EndpointSubset#notReadyAddresses
        '''
        result = self._values.get("not_ready_addresses")
        return typing.cast(typing.Optional[typing.List[EndpointAddress]], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List[EndpointPort]]:
        '''Port numbers available on the related IP addresses.

        :schema: io.k8s.api.core.v1.EndpointSubset#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List[EndpointPort]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointSubset(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EndpointV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "addresses": "addresses",
        "conditions": "conditions",
        "hints": "hints",
        "hostname": "hostname",
        "node_name": "nodeName",
        "target_ref": "targetRef",
        "topology": "topology",
    },
)
class EndpointV1Beta1:
    def __init__(
        self,
        *,
        addresses: typing.Sequence[builtins.str],
        conditions: typing.Optional[typing.Union[EndpointConditionsV1Beta1, typing.Dict[str, typing.Any]]] = None,
        hints: typing.Optional[typing.Union[EndpointHintsV1Beta1, typing.Dict[str, typing.Any]]] = None,
        hostname: typing.Optional[builtins.str] = None,
        node_name: typing.Optional[builtins.str] = None,
        target_ref: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        topology: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
    ) -> None:
        '''Endpoint represents a single logical "backend" implementing a service.

        :param addresses: addresses of this endpoint. The contents of this field are interpreted according to the corresponding EndpointSlice addressType field. Consumers must handle different types of addresses in the context of their own capabilities. This must contain at least one address but no more than 100.
        :param conditions: conditions contains information about the current status of the endpoint.
        :param hints: hints contains information associated with how an endpoint should be consumed.
        :param hostname: hostname of this endpoint. This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.
        :param node_name: nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node. This field can be enabled with the EndpointSliceNodeName feature gate.
        :param target_ref: targetRef is a reference to a Kubernetes object that represents this endpoint.
        :param topology: topology contains arbitrary topology information associated with the endpoint. These key/value pairs must conform with the label format. https://kubernetes.io/docs/concepts/overview/working-with-objects/labels Topology may include a maximum of 16 key/value pairs. This includes, but is not limited to the following well known keys: * kubernetes.io/hostname: the value indicates the hostname of the node where the endpoint is located. This should match the corresponding node label. - topology.kubernetes.io/zone: the value indicates the zone where the endpoint is located. This should match the corresponding node label. - topology.kubernetes.io/region: the value indicates the region where the endpoint is located. This should match the corresponding node label. This field is deprecated and will be removed in future api versions.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint
        '''
        if isinstance(conditions, dict):
            conditions = EndpointConditionsV1Beta1(**conditions)
        if isinstance(hints, dict):
            hints = EndpointHintsV1Beta1(**hints)
        if isinstance(target_ref, dict):
            target_ref = ObjectReference(**target_ref)
        if __debug__:
            def stub(
                *,
                addresses: typing.Sequence[builtins.str],
                conditions: typing.Optional[typing.Union[EndpointConditionsV1Beta1, typing.Dict[str, typing.Any]]] = None,
                hints: typing.Optional[typing.Union[EndpointHintsV1Beta1, typing.Dict[str, typing.Any]]] = None,
                hostname: typing.Optional[builtins.str] = None,
                node_name: typing.Optional[builtins.str] = None,
                target_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                topology: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument addresses", value=addresses, expected_type=type_hints["addresses"])
            check_type(argname="argument conditions", value=conditions, expected_type=type_hints["conditions"])
            check_type(argname="argument hints", value=hints, expected_type=type_hints["hints"])
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument node_name", value=node_name, expected_type=type_hints["node_name"])
            check_type(argname="argument target_ref", value=target_ref, expected_type=type_hints["target_ref"])
            check_type(argname="argument topology", value=topology, expected_type=type_hints["topology"])
        self._values: typing.Dict[str, typing.Any] = {
            "addresses": addresses,
        }
        if conditions is not None:
            self._values["conditions"] = conditions
        if hints is not None:
            self._values["hints"] = hints
        if hostname is not None:
            self._values["hostname"] = hostname
        if node_name is not None:
            self._values["node_name"] = node_name
        if target_ref is not None:
            self._values["target_ref"] = target_ref
        if topology is not None:
            self._values["topology"] = topology

    @builtins.property
    def addresses(self) -> typing.List[builtins.str]:
        '''addresses of this endpoint.

        The contents of this field are interpreted according to the corresponding EndpointSlice addressType field. Consumers must handle different types of addresses in the context of their own capabilities. This must contain at least one address but no more than 100.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#addresses
        '''
        result = self._values.get("addresses")
        assert result is not None, "Required property 'addresses' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def conditions(self) -> typing.Optional[EndpointConditionsV1Beta1]:
        '''conditions contains information about the current status of the endpoint.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#conditions
        '''
        result = self._values.get("conditions")
        return typing.cast(typing.Optional[EndpointConditionsV1Beta1], result)

    @builtins.property
    def hints(self) -> typing.Optional[EndpointHintsV1Beta1]:
        '''hints contains information associated with how an endpoint should be consumed.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#hints
        '''
        result = self._values.get("hints")
        return typing.cast(typing.Optional[EndpointHintsV1Beta1], result)

    @builtins.property
    def hostname(self) -> typing.Optional[builtins.str]:
        '''hostname of this endpoint.

        This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#hostname
        '''
        result = self._values.get("hostname")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_name(self) -> typing.Optional[builtins.str]:
        '''nodeName represents the name of the Node hosting this endpoint.

        This can be used to determine endpoints local to a Node. This field can be enabled with the EndpointSliceNodeName feature gate.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#nodeName
        '''
        result = self._values.get("node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def target_ref(self) -> typing.Optional["ObjectReference"]:
        '''targetRef is a reference to a Kubernetes object that represents this endpoint.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#targetRef
        '''
        result = self._values.get("target_ref")
        return typing.cast(typing.Optional["ObjectReference"], result)

    @builtins.property
    def topology(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''topology contains arbitrary topology information associated with the endpoint.

        These key/value pairs must conform with the label format. https://kubernetes.io/docs/concepts/overview/working-with-objects/labels Topology may include a maximum of 16 key/value pairs. This includes, but is not limited to the following well known keys: * kubernetes.io/hostname: the value indicates the hostname of the node
        where the endpoint is located. This should match the corresponding
        node label.

        - topology.kubernetes.io/zone: the value indicates the zone where the
          endpoint is located. This should match the corresponding node label.
        - topology.kubernetes.io/region: the value indicates the region where the
          endpoint is located. This should match the corresponding node label.
          This field is deprecated and will be removed in future api versions.

        :schema: io.k8s.api.discovery.v1beta1.Endpoint#topology
        '''
        result = self._values.get("topology")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EndpointV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EnvFromSource",
    jsii_struct_bases=[],
    name_mapping={
        "config_map_ref": "configMapRef",
        "prefix": "prefix",
        "secret_ref": "secretRef",
    },
)
class EnvFromSource:
    def __init__(
        self,
        *,
        config_map_ref: typing.Optional[typing.Union[ConfigMapEnvSource, typing.Dict[str, typing.Any]]] = None,
        prefix: typing.Optional[builtins.str] = None,
        secret_ref: typing.Optional[typing.Union["SecretEnvSource", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EnvFromSource represents the source of a set of ConfigMaps.

        :param config_map_ref: The ConfigMap to select from.
        :param prefix: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
        :param secret_ref: The Secret to select from.

        :schema: io.k8s.api.core.v1.EnvFromSource
        '''
        if isinstance(config_map_ref, dict):
            config_map_ref = ConfigMapEnvSource(**config_map_ref)
        if isinstance(secret_ref, dict):
            secret_ref = SecretEnvSource(**secret_ref)
        if __debug__:
            def stub(
                *,
                config_map_ref: typing.Optional[typing.Union[ConfigMapEnvSource, typing.Dict[str, typing.Any]]] = None,
                prefix: typing.Optional[builtins.str] = None,
                secret_ref: typing.Optional[typing.Union[SecretEnvSource, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument config_map_ref", value=config_map_ref, expected_type=type_hints["config_map_ref"])
            check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {}
        if config_map_ref is not None:
            self._values["config_map_ref"] = config_map_ref
        if prefix is not None:
            self._values["prefix"] = prefix
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def config_map_ref(self) -> typing.Optional[ConfigMapEnvSource]:
        '''The ConfigMap to select from.

        :schema: io.k8s.api.core.v1.EnvFromSource#configMapRef
        '''
        result = self._values.get("config_map_ref")
        return typing.cast(typing.Optional[ConfigMapEnvSource], result)

    @builtins.property
    def prefix(self) -> typing.Optional[builtins.str]:
        '''An optional identifier to prepend to each key in the ConfigMap.

        Must be a C_IDENTIFIER.

        :schema: io.k8s.api.core.v1.EnvFromSource#prefix
        '''
        result = self._values.get("prefix")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["SecretEnvSource"]:
        '''The Secret to select from.

        :schema: io.k8s.api.core.v1.EnvFromSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["SecretEnvSource"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EnvFromSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EnvVar",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "value": "value", "value_from": "valueFrom"},
)
class EnvVar:
    def __init__(
        self,
        *,
        name: builtins.str,
        value: typing.Optional[builtins.str] = None,
        value_from: typing.Optional[typing.Union["EnvVarSource", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EnvVar represents an environment variable present in a Container.

        :param name: Name of the environment variable. Must be a C_IDENTIFIER.
        :param value: Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "". Default: .
        :param value_from: Source for the environment variable's value. Cannot be used if value is not empty.

        :schema: io.k8s.api.core.v1.EnvVar
        '''
        if isinstance(value_from, dict):
            value_from = EnvVarSource(**value_from)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                value: typing.Optional[builtins.str] = None,
                value_from: typing.Optional[typing.Union[EnvVarSource, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            check_type(argname="argument value_from", value=value_from, expected_type=type_hints["value_from"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if value is not None:
            self._values["value"] = value
        if value_from is not None:
            self._values["value_from"] = value_from

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the environment variable.

        Must be a C_IDENTIFIER.

        :schema: io.k8s.api.core.v1.EnvVar#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def value(self) -> typing.Optional[builtins.str]:
        '''Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables.

        If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".

        :default: .

        :schema: io.k8s.api.core.v1.EnvVar#value
        '''
        result = self._values.get("value")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def value_from(self) -> typing.Optional["EnvVarSource"]:
        '''Source for the environment variable's value.

        Cannot be used if value is not empty.

        :schema: io.k8s.api.core.v1.EnvVar#valueFrom
        '''
        result = self._values.get("value_from")
        return typing.cast(typing.Optional["EnvVarSource"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EnvVar(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EnvVarSource",
    jsii_struct_bases=[],
    name_mapping={
        "config_map_key_ref": "configMapKeyRef",
        "field_ref": "fieldRef",
        "resource_field_ref": "resourceFieldRef",
        "secret_key_ref": "secretKeyRef",
    },
)
class EnvVarSource:
    def __init__(
        self,
        *,
        config_map_key_ref: typing.Optional[typing.Union[ConfigMapKeySelector, typing.Dict[str, typing.Any]]] = None,
        field_ref: typing.Optional[typing.Union["ObjectFieldSelector", typing.Dict[str, typing.Any]]] = None,
        resource_field_ref: typing.Optional[typing.Union["ResourceFieldSelector", typing.Dict[str, typing.Any]]] = None,
        secret_key_ref: typing.Optional[typing.Union["SecretKeySelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EnvVarSource represents a source for the value of an EnvVar.

        :param config_map_key_ref: Selects a key of a ConfigMap.
        :param field_ref: Selects a field of the pod: supports metadata.name, metadata.namespace, ``metadata.labels['<KEY>']``, ``metadata.annotations['<KEY>']``, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
        :param resource_field_ref: Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
        :param secret_key_ref: Selects a key of a secret in the pod's namespace.

        :schema: io.k8s.api.core.v1.EnvVarSource
        '''
        if isinstance(config_map_key_ref, dict):
            config_map_key_ref = ConfigMapKeySelector(**config_map_key_ref)
        if isinstance(field_ref, dict):
            field_ref = ObjectFieldSelector(**field_ref)
        if isinstance(resource_field_ref, dict):
            resource_field_ref = ResourceFieldSelector(**resource_field_ref)
        if isinstance(secret_key_ref, dict):
            secret_key_ref = SecretKeySelector(**secret_key_ref)
        if __debug__:
            def stub(
                *,
                config_map_key_ref: typing.Optional[typing.Union[ConfigMapKeySelector, typing.Dict[str, typing.Any]]] = None,
                field_ref: typing.Optional[typing.Union[ObjectFieldSelector, typing.Dict[str, typing.Any]]] = None,
                resource_field_ref: typing.Optional[typing.Union[ResourceFieldSelector, typing.Dict[str, typing.Any]]] = None,
                secret_key_ref: typing.Optional[typing.Union[SecretKeySelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument config_map_key_ref", value=config_map_key_ref, expected_type=type_hints["config_map_key_ref"])
            check_type(argname="argument field_ref", value=field_ref, expected_type=type_hints["field_ref"])
            check_type(argname="argument resource_field_ref", value=resource_field_ref, expected_type=type_hints["resource_field_ref"])
            check_type(argname="argument secret_key_ref", value=secret_key_ref, expected_type=type_hints["secret_key_ref"])
        self._values: typing.Dict[str, typing.Any] = {}
        if config_map_key_ref is not None:
            self._values["config_map_key_ref"] = config_map_key_ref
        if field_ref is not None:
            self._values["field_ref"] = field_ref
        if resource_field_ref is not None:
            self._values["resource_field_ref"] = resource_field_ref
        if secret_key_ref is not None:
            self._values["secret_key_ref"] = secret_key_ref

    @builtins.property
    def config_map_key_ref(self) -> typing.Optional[ConfigMapKeySelector]:
        '''Selects a key of a ConfigMap.

        :schema: io.k8s.api.core.v1.EnvVarSource#configMapKeyRef
        '''
        result = self._values.get("config_map_key_ref")
        return typing.cast(typing.Optional[ConfigMapKeySelector], result)

    @builtins.property
    def field_ref(self) -> typing.Optional["ObjectFieldSelector"]:
        '''Selects a field of the pod: supports metadata.name, metadata.namespace, ``metadata.labels['<KEY>']``, ``metadata.annotations['<KEY>']``, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.

        :schema: io.k8s.api.core.v1.EnvVarSource#fieldRef
        '''
        result = self._values.get("field_ref")
        return typing.cast(typing.Optional["ObjectFieldSelector"], result)

    @builtins.property
    def resource_field_ref(self) -> typing.Optional["ResourceFieldSelector"]:
        '''Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.

        :schema: io.k8s.api.core.v1.EnvVarSource#resourceFieldRef
        '''
        result = self._values.get("resource_field_ref")
        return typing.cast(typing.Optional["ResourceFieldSelector"], result)

    @builtins.property
    def secret_key_ref(self) -> typing.Optional["SecretKeySelector"]:
        '''Selects a key of a secret in the pod's namespace.

        :schema: io.k8s.api.core.v1.EnvVarSource#secretKeyRef
        '''
        result = self._values.get("secret_key_ref")
        return typing.cast(typing.Optional["SecretKeySelector"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EnvVarSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EphemeralContainer",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "args": "args",
        "command": "command",
        "env": "env",
        "env_from": "envFrom",
        "image": "image",
        "image_pull_policy": "imagePullPolicy",
        "lifecycle": "lifecycle",
        "liveness_probe": "livenessProbe",
        "ports": "ports",
        "readiness_probe": "readinessProbe",
        "resources": "resources",
        "security_context": "securityContext",
        "startup_probe": "startupProbe",
        "stdin": "stdin",
        "stdin_once": "stdinOnce",
        "target_container_name": "targetContainerName",
        "termination_message_path": "terminationMessagePath",
        "termination_message_policy": "terminationMessagePolicy",
        "tty": "tty",
        "volume_devices": "volumeDevices",
        "volume_mounts": "volumeMounts",
        "working_dir": "workingDir",
    },
)
class EphemeralContainer:
    def __init__(
        self,
        *,
        name: builtins.str,
        args: typing.Optional[typing.Sequence[builtins.str]] = None,
        command: typing.Optional[typing.Sequence[builtins.str]] = None,
        env: typing.Optional[typing.Sequence[typing.Union[EnvVar, typing.Dict[str, typing.Any]]]] = None,
        env_from: typing.Optional[typing.Sequence[typing.Union[EnvFromSource, typing.Dict[str, typing.Any]]]] = None,
        image: typing.Optional[builtins.str] = None,
        image_pull_policy: typing.Optional["IoK8SApiCoreV1EphemeralContainerImagePullPolicy"] = None,
        lifecycle: typing.Optional[typing.Union["Lifecycle", typing.Dict[str, typing.Any]]] = None,
        liveness_probe: typing.Optional[typing.Union["Probe", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[ContainerPort, typing.Dict[str, typing.Any]]]] = None,
        readiness_probe: typing.Optional[typing.Union["Probe", typing.Dict[str, typing.Any]]] = None,
        resources: typing.Optional[typing.Union["ResourceRequirements", typing.Dict[str, typing.Any]]] = None,
        security_context: typing.Optional[typing.Union["SecurityContext", typing.Dict[str, typing.Any]]] = None,
        startup_probe: typing.Optional[typing.Union["Probe", typing.Dict[str, typing.Any]]] = None,
        stdin: typing.Optional[builtins.bool] = None,
        stdin_once: typing.Optional[builtins.bool] = None,
        target_container_name: typing.Optional[builtins.str] = None,
        termination_message_path: typing.Optional[builtins.str] = None,
        termination_message_policy: typing.Optional["IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy"] = None,
        tty: typing.Optional[builtins.bool] = None,
        volume_devices: typing.Optional[typing.Sequence[typing.Union["VolumeDevice", typing.Dict[str, typing.Any]]]] = None,
        volume_mounts: typing.Optional[typing.Sequence[typing.Union["VolumeMount", typing.Dict[str, typing.Any]]]] = None,
        working_dir: typing.Optional[builtins.str] = None,
    ) -> None:
        '''An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging.

        Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.

        To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.

        This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.

        :param name: Name of the ephemeral container specified as a DNS_LABEL. This name must be unique among all containers, init containers and ephemeral containers.
        :param args: Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
        :param command: Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
        :param env: List of environment variables to set in the container. Cannot be updated.
        :param env_from: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.
        :param image: Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images
        :param image_pull_policy: Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images Possible enum values: - ``"Always"`` means that kubelet always attempts to pull the latest image. Container will fail If the pull fails. - ``"IfNotPresent"`` means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails. - ``"Never"`` means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present Default: Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
        :param lifecycle: Lifecycle is not allowed for ephemeral containers.
        :param liveness_probe: Probes are not allowed for ephemeral containers.
        :param ports: Ports are not allowed for ephemeral containers.
        :param readiness_probe: Probes are not allowed for ephemeral containers.
        :param resources: Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod.
        :param security_context: Optional: SecurityContext defines the security options the ephemeral container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
        :param startup_probe: Probes are not allowed for ephemeral containers.
        :param stdin: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. Default: false.
        :param stdin_once: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false Default: false
        :param target_container_name: If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec. The container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined.
        :param termination_message_path: Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated. Default: dev/termination-log. Cannot be updated.
        :param termination_message_policy: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. Possible enum values: - ``"FallbackToLogsOnError"`` will read the most recent contents of the container logs for the container status message when the container exits with an error and the terminationMessagePath has no contents. - ``"File"`` is the default behavior and will set the container status message to the contents of the container's terminationMessagePath when the container exits. Default: File. Cannot be updated.
        :param tty: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. Default: false.
        :param volume_devices: volumeDevices is the list of block devices to be used by the container.
        :param volume_mounts: Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated.
        :param working_dir: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer
        '''
        if isinstance(lifecycle, dict):
            lifecycle = Lifecycle(**lifecycle)
        if isinstance(liveness_probe, dict):
            liveness_probe = Probe(**liveness_probe)
        if isinstance(readiness_probe, dict):
            readiness_probe = Probe(**readiness_probe)
        if isinstance(resources, dict):
            resources = ResourceRequirements(**resources)
        if isinstance(security_context, dict):
            security_context = SecurityContext(**security_context)
        if isinstance(startup_probe, dict):
            startup_probe = Probe(**startup_probe)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                args: typing.Optional[typing.Sequence[builtins.str]] = None,
                command: typing.Optional[typing.Sequence[builtins.str]] = None,
                env: typing.Optional[typing.Sequence[typing.Union[EnvVar, typing.Dict[str, typing.Any]]]] = None,
                env_from: typing.Optional[typing.Sequence[typing.Union[EnvFromSource, typing.Dict[str, typing.Any]]]] = None,
                image: typing.Optional[builtins.str] = None,
                image_pull_policy: typing.Optional[IoK8SApiCoreV1EphemeralContainerImagePullPolicy] = None,
                lifecycle: typing.Optional[typing.Union[Lifecycle, typing.Dict[str, typing.Any]]] = None,
                liveness_probe: typing.Optional[typing.Union[Probe, typing.Dict[str, typing.Any]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[ContainerPort, typing.Dict[str, typing.Any]]]] = None,
                readiness_probe: typing.Optional[typing.Union[Probe, typing.Dict[str, typing.Any]]] = None,
                resources: typing.Optional[typing.Union[ResourceRequirements, typing.Dict[str, typing.Any]]] = None,
                security_context: typing.Optional[typing.Union[SecurityContext, typing.Dict[str, typing.Any]]] = None,
                startup_probe: typing.Optional[typing.Union[Probe, typing.Dict[str, typing.Any]]] = None,
                stdin: typing.Optional[builtins.bool] = None,
                stdin_once: typing.Optional[builtins.bool] = None,
                target_container_name: typing.Optional[builtins.str] = None,
                termination_message_path: typing.Optional[builtins.str] = None,
                termination_message_policy: typing.Optional[IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy] = None,
                tty: typing.Optional[builtins.bool] = None,
                volume_devices: typing.Optional[typing.Sequence[typing.Union[VolumeDevice, typing.Dict[str, typing.Any]]]] = None,
                volume_mounts: typing.Optional[typing.Sequence[typing.Union[VolumeMount, typing.Dict[str, typing.Any]]]] = None,
                working_dir: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument args", value=args, expected_type=type_hints["args"])
            check_type(argname="argument command", value=command, expected_type=type_hints["command"])
            check_type(argname="argument env", value=env, expected_type=type_hints["env"])
            check_type(argname="argument env_from", value=env_from, expected_type=type_hints["env_from"])
            check_type(argname="argument image", value=image, expected_type=type_hints["image"])
            check_type(argname="argument image_pull_policy", value=image_pull_policy, expected_type=type_hints["image_pull_policy"])
            check_type(argname="argument lifecycle", value=lifecycle, expected_type=type_hints["lifecycle"])
            check_type(argname="argument liveness_probe", value=liveness_probe, expected_type=type_hints["liveness_probe"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
            check_type(argname="argument readiness_probe", value=readiness_probe, expected_type=type_hints["readiness_probe"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
            check_type(argname="argument security_context", value=security_context, expected_type=type_hints["security_context"])
            check_type(argname="argument startup_probe", value=startup_probe, expected_type=type_hints["startup_probe"])
            check_type(argname="argument stdin", value=stdin, expected_type=type_hints["stdin"])
            check_type(argname="argument stdin_once", value=stdin_once, expected_type=type_hints["stdin_once"])
            check_type(argname="argument target_container_name", value=target_container_name, expected_type=type_hints["target_container_name"])
            check_type(argname="argument termination_message_path", value=termination_message_path, expected_type=type_hints["termination_message_path"])
            check_type(argname="argument termination_message_policy", value=termination_message_policy, expected_type=type_hints["termination_message_policy"])
            check_type(argname="argument tty", value=tty, expected_type=type_hints["tty"])
            check_type(argname="argument volume_devices", value=volume_devices, expected_type=type_hints["volume_devices"])
            check_type(argname="argument volume_mounts", value=volume_mounts, expected_type=type_hints["volume_mounts"])
            check_type(argname="argument working_dir", value=working_dir, expected_type=type_hints["working_dir"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if args is not None:
            self._values["args"] = args
        if command is not None:
            self._values["command"] = command
        if env is not None:
            self._values["env"] = env
        if env_from is not None:
            self._values["env_from"] = env_from
        if image is not None:
            self._values["image"] = image
        if image_pull_policy is not None:
            self._values["image_pull_policy"] = image_pull_policy
        if lifecycle is not None:
            self._values["lifecycle"] = lifecycle
        if liveness_probe is not None:
            self._values["liveness_probe"] = liveness_probe
        if ports is not None:
            self._values["ports"] = ports
        if readiness_probe is not None:
            self._values["readiness_probe"] = readiness_probe
        if resources is not None:
            self._values["resources"] = resources
        if security_context is not None:
            self._values["security_context"] = security_context
        if startup_probe is not None:
            self._values["startup_probe"] = startup_probe
        if stdin is not None:
            self._values["stdin"] = stdin
        if stdin_once is not None:
            self._values["stdin_once"] = stdin_once
        if target_container_name is not None:
            self._values["target_container_name"] = target_container_name
        if termination_message_path is not None:
            self._values["termination_message_path"] = termination_message_path
        if termination_message_policy is not None:
            self._values["termination_message_policy"] = termination_message_policy
        if tty is not None:
            self._values["tty"] = tty
        if volume_devices is not None:
            self._values["volume_devices"] = volume_devices
        if volume_mounts is not None:
            self._values["volume_mounts"] = volume_mounts
        if working_dir is not None:
            self._values["working_dir"] = working_dir

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the ephemeral container specified as a DNS_LABEL.

        This name must be unique among all containers, init containers and ephemeral containers.

        :schema: io.k8s.api.core.v1.EphemeralContainer#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def args(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Arguments to the entrypoint.

        The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

        :schema: io.k8s.api.core.v1.EphemeralContainer#args
        '''
        result = self._values.get("args")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def command(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Entrypoint array.

        Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

        :schema: io.k8s.api.core.v1.EphemeralContainer#command
        '''
        result = self._values.get("command")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def env(self) -> typing.Optional[typing.List[EnvVar]]:
        '''List of environment variables to set in the container.

        Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer#env
        '''
        result = self._values.get("env")
        return typing.cast(typing.Optional[typing.List[EnvVar]], result)

    @builtins.property
    def env_from(self) -> typing.Optional[typing.List[EnvFromSource]]:
        '''List of sources to populate environment variables in the container.

        The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer#envFrom
        '''
        result = self._values.get("env_from")
        return typing.cast(typing.Optional[typing.List[EnvFromSource]], result)

    @builtins.property
    def image(self) -> typing.Optional[builtins.str]:
        '''Docker image name.

        More info: https://kubernetes.io/docs/concepts/containers/images

        :schema: io.k8s.api.core.v1.EphemeralContainer#image
        '''
        result = self._values.get("image")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def image_pull_policy(
        self,
    ) -> typing.Optional["IoK8SApiCoreV1EphemeralContainerImagePullPolicy"]:
        '''Image pull policy.

        One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

        Possible enum values:

        - ``"Always"`` means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
        - ``"IfNotPresent"`` means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails.
        - ``"Never"`` means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present

        :default: Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

        :schema: io.k8s.api.core.v1.EphemeralContainer#imagePullPolicy
        '''
        result = self._values.get("image_pull_policy")
        return typing.cast(typing.Optional["IoK8SApiCoreV1EphemeralContainerImagePullPolicy"], result)

    @builtins.property
    def lifecycle(self) -> typing.Optional["Lifecycle"]:
        '''Lifecycle is not allowed for ephemeral containers.

        :schema: io.k8s.api.core.v1.EphemeralContainer#lifecycle
        '''
        result = self._values.get("lifecycle")
        return typing.cast(typing.Optional["Lifecycle"], result)

    @builtins.property
    def liveness_probe(self) -> typing.Optional["Probe"]:
        '''Probes are not allowed for ephemeral containers.

        :schema: io.k8s.api.core.v1.EphemeralContainer#livenessProbe
        '''
        result = self._values.get("liveness_probe")
        return typing.cast(typing.Optional["Probe"], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List[ContainerPort]]:
        '''Ports are not allowed for ephemeral containers.

        :schema: io.k8s.api.core.v1.EphemeralContainer#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List[ContainerPort]], result)

    @builtins.property
    def readiness_probe(self) -> typing.Optional["Probe"]:
        '''Probes are not allowed for ephemeral containers.

        :schema: io.k8s.api.core.v1.EphemeralContainer#readinessProbe
        '''
        result = self._values.get("readiness_probe")
        return typing.cast(typing.Optional["Probe"], result)

    @builtins.property
    def resources(self) -> typing.Optional["ResourceRequirements"]:
        '''Resources are not allowed for ephemeral containers.

        Ephemeral containers use spare resources already allocated to the pod.

        :schema: io.k8s.api.core.v1.EphemeralContainer#resources
        '''
        result = self._values.get("resources")
        return typing.cast(typing.Optional["ResourceRequirements"], result)

    @builtins.property
    def security_context(self) -> typing.Optional["SecurityContext"]:
        '''Optional: SecurityContext defines the security options the ephemeral container should be run with.

        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.

        :schema: io.k8s.api.core.v1.EphemeralContainer#securityContext
        '''
        result = self._values.get("security_context")
        return typing.cast(typing.Optional["SecurityContext"], result)

    @builtins.property
    def startup_probe(self) -> typing.Optional["Probe"]:
        '''Probes are not allowed for ephemeral containers.

        :schema: io.k8s.api.core.v1.EphemeralContainer#startupProbe
        '''
        result = self._values.get("startup_probe")
        return typing.cast(typing.Optional["Probe"], result)

    @builtins.property
    def stdin(self) -> typing.Optional[builtins.bool]:
        '''Whether this container should allocate a buffer for stdin in the container runtime.

        If this is not set, reads from stdin in the container will always result in EOF. Default is false.

        :default: false.

        :schema: io.k8s.api.core.v1.EphemeralContainer#stdin
        '''
        result = self._values.get("stdin")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def stdin_once(self) -> typing.Optional[builtins.bool]:
        '''Whether the container runtime should close the stdin channel after it has been opened by a single attach.

        When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false

        :default: false

        :schema: io.k8s.api.core.v1.EphemeralContainer#stdinOnce
        '''
        result = self._values.get("stdin_once")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def target_container_name(self) -> typing.Optional[builtins.str]:
        '''If set, the name of the container from PodSpec that this ephemeral container targets.

        The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec.

        The container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined.

        :schema: io.k8s.api.core.v1.EphemeralContainer#targetContainerName
        '''
        result = self._values.get("target_container_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def termination_message_path(self) -> typing.Optional[builtins.str]:
        '''Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem.

        Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

        :default: dev/termination-log. Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer#terminationMessagePath
        '''
        result = self._values.get("termination_message_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def termination_message_policy(
        self,
    ) -> typing.Optional["IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy"]:
        '''Indicate how the termination message should be populated.

        File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

        Possible enum values:

        - ``"FallbackToLogsOnError"`` will read the most recent contents of the container logs for the container status message when the container exits with an error and the terminationMessagePath has no contents.
        - ``"File"`` is the default behavior and will set the container status message to the contents of the container's terminationMessagePath when the container exits.

        :default: File. Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer#terminationMessagePolicy
        '''
        result = self._values.get("termination_message_policy")
        return typing.cast(typing.Optional["IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy"], result)

    @builtins.property
    def tty(self) -> typing.Optional[builtins.bool]:
        '''Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.

        Default is false.

        :default: false.

        :schema: io.k8s.api.core.v1.EphemeralContainer#tty
        '''
        result = self._values.get("tty")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def volume_devices(self) -> typing.Optional[typing.List["VolumeDevice"]]:
        '''volumeDevices is the list of block devices to be used by the container.

        :schema: io.k8s.api.core.v1.EphemeralContainer#volumeDevices
        '''
        result = self._values.get("volume_devices")
        return typing.cast(typing.Optional[typing.List["VolumeDevice"]], result)

    @builtins.property
    def volume_mounts(self) -> typing.Optional[typing.List["VolumeMount"]]:
        '''Pod volumes to mount into the container's filesystem.

        Subpath mounts are not allowed for ephemeral containers. Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer#volumeMounts
        '''
        result = self._values.get("volume_mounts")
        return typing.cast(typing.Optional[typing.List["VolumeMount"]], result)

    @builtins.property
    def working_dir(self) -> typing.Optional[builtins.str]:
        '''Container's working directory.

        If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.

        :schema: io.k8s.api.core.v1.EphemeralContainer#workingDir
        '''
        result = self._values.get("working_dir")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EphemeralContainer(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EphemeralVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"volume_claim_template": "volumeClaimTemplate"},
)
class EphemeralVolumeSource:
    def __init__(
        self,
        *,
        volume_claim_template: typing.Optional[typing.Union["PersistentVolumeClaimTemplate", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents an ephemeral volume that is handled by a normal storage driver.

        :param volume_claim_template: Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be ``<pod name>-<volume name>`` where ``<volume name>`` is the name from the ``PodSpec.Volumes`` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. Required, must not be nil.

        :schema: io.k8s.api.core.v1.EphemeralVolumeSource
        '''
        if isinstance(volume_claim_template, dict):
            volume_claim_template = PersistentVolumeClaimTemplate(**volume_claim_template)
        if __debug__:
            def stub(
                *,
                volume_claim_template: typing.Optional[typing.Union[PersistentVolumeClaimTemplate, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument volume_claim_template", value=volume_claim_template, expected_type=type_hints["volume_claim_template"])
        self._values: typing.Dict[str, typing.Any] = {}
        if volume_claim_template is not None:
            self._values["volume_claim_template"] = volume_claim_template

    @builtins.property
    def volume_claim_template(self) -> typing.Optional["PersistentVolumeClaimTemplate"]:
        '''Will be used to create a stand-alone PVC to provision the volume.

        The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod.  The name of the PVC will be ``<pod name>-<volume name>`` where ``<volume name>`` is the name from the ``PodSpec.Volumes`` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long).

        An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster.

        This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created.

        Required, must not be nil.

        :schema: io.k8s.api.core.v1.EphemeralVolumeSource#volumeClaimTemplate
        '''
        result = self._values.get("volume_claim_template")
        return typing.cast(typing.Optional["PersistentVolumeClaimTemplate"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EphemeralVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EventSeries",
    jsii_struct_bases=[],
    name_mapping={"count": "count", "last_observed_time": "lastObservedTime"},
)
class EventSeries:
    def __init__(
        self,
        *,
        count: jsii.Number,
        last_observed_time: datetime.datetime,
    ) -> None:
        '''EventSeries contain information on series of events, i.e. thing that was/is happening continuously for some time. How often to update the EventSeries is up to the event reporters. The default event reporter in "k8s.io/client-go/tools/events/event_broadcaster.go" shows how this struct is updated on heartbeats and can guide customized reporter implementations.

        :param count: count is the number of occurrences in this series up to the last heartbeat time.
        :param last_observed_time: lastObservedTime is the time when last Event from the series was seen before last heartbeat.

        :schema: io.k8s.api.events.v1.EventSeries
        '''
        if __debug__:
            def stub(
                *,
                count: jsii.Number,
                last_observed_time: datetime.datetime,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument count", value=count, expected_type=type_hints["count"])
            check_type(argname="argument last_observed_time", value=last_observed_time, expected_type=type_hints["last_observed_time"])
        self._values: typing.Dict[str, typing.Any] = {
            "count": count,
            "last_observed_time": last_observed_time,
        }

    @builtins.property
    def count(self) -> jsii.Number:
        '''count is the number of occurrences in this series up to the last heartbeat time.

        :schema: io.k8s.api.events.v1.EventSeries#count
        '''
        result = self._values.get("count")
        assert result is not None, "Required property 'count' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def last_observed_time(self) -> datetime.datetime:
        '''lastObservedTime is the time when last Event from the series was seen before last heartbeat.

        :schema: io.k8s.api.events.v1.EventSeries#lastObservedTime
        '''
        result = self._values.get("last_observed_time")
        assert result is not None, "Required property 'last_observed_time' is missing"
        return typing.cast(datetime.datetime, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EventSeries(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EventSeriesV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"count": "count", "last_observed_time": "lastObservedTime"},
)
class EventSeriesV1Beta1:
    def __init__(
        self,
        *,
        count: jsii.Number,
        last_observed_time: datetime.datetime,
    ) -> None:
        '''EventSeries contain information on series of events, i.e. thing that was/is happening continuously for some time.

        :param count: count is the number of occurrences in this series up to the last heartbeat time.
        :param last_observed_time: lastObservedTime is the time when last Event from the series was seen before last heartbeat.

        :schema: io.k8s.api.events.v1beta1.EventSeries
        '''
        if __debug__:
            def stub(
                *,
                count: jsii.Number,
                last_observed_time: datetime.datetime,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument count", value=count, expected_type=type_hints["count"])
            check_type(argname="argument last_observed_time", value=last_observed_time, expected_type=type_hints["last_observed_time"])
        self._values: typing.Dict[str, typing.Any] = {
            "count": count,
            "last_observed_time": last_observed_time,
        }

    @builtins.property
    def count(self) -> jsii.Number:
        '''count is the number of occurrences in this series up to the last heartbeat time.

        :schema: io.k8s.api.events.v1beta1.EventSeries#count
        '''
        result = self._values.get("count")
        assert result is not None, "Required property 'count' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def last_observed_time(self) -> datetime.datetime:
        '''lastObservedTime is the time when last Event from the series was seen before last heartbeat.

        :schema: io.k8s.api.events.v1beta1.EventSeries#lastObservedTime
        '''
        result = self._values.get("last_observed_time")
        assert result is not None, "Required property 'last_observed_time' is missing"
        return typing.cast(datetime.datetime, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EventSeriesV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.EventSource",
    jsii_struct_bases=[],
    name_mapping={"component": "component", "host": "host"},
)
class EventSource:
    def __init__(
        self,
        *,
        component: typing.Optional[builtins.str] = None,
        host: typing.Optional[builtins.str] = None,
    ) -> None:
        '''EventSource contains information for an event.

        :param component: Component from which the event is generated.
        :param host: Node name on which the event is generated.

        :schema: io.k8s.api.core.v1.EventSource
        '''
        if __debug__:
            def stub(
                *,
                component: typing.Optional[builtins.str] = None,
                host: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument component", value=component, expected_type=type_hints["component"])
            check_type(argname="argument host", value=host, expected_type=type_hints["host"])
        self._values: typing.Dict[str, typing.Any] = {}
        if component is not None:
            self._values["component"] = component
        if host is not None:
            self._values["host"] = host

    @builtins.property
    def component(self) -> typing.Optional[builtins.str]:
        '''Component from which the event is generated.

        :schema: io.k8s.api.core.v1.EventSource#component
        '''
        result = self._values.get("component")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def host(self) -> typing.Optional[builtins.str]:
        '''Node name on which the event is generated.

        :schema: io.k8s.api.core.v1.EventSource#host
        '''
        result = self._values.get("host")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EventSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ExecAction",
    jsii_struct_bases=[],
    name_mapping={"command": "command"},
)
class ExecAction:
    def __init__(
        self,
        *,
        command: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''ExecAction describes a "run in container" action.

        :param command: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy.

        :schema: io.k8s.api.core.v1.ExecAction
        '''
        if __debug__:
            def stub(
                *,
                command: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument command", value=command, expected_type=type_hints["command"])
        self._values: typing.Dict[str, typing.Any] = {}
        if command is not None:
            self._values["command"] = command

    @builtins.property
    def command(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Command is the command line to execute inside the container, the working directory for the command  is root ('/') in the container's filesystem.

        The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy.

        :schema: io.k8s.api.core.v1.ExecAction#command
        '''
        result = self._values.get("command")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ExecAction(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ExternalDocumentation",
    jsii_struct_bases=[],
    name_mapping={"description": "description", "url": "url"},
)
class ExternalDocumentation:
    def __init__(
        self,
        *,
        description: typing.Optional[builtins.str] = None,
        url: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ExternalDocumentation allows referencing an external resource for extended documentation.

        :param description: 
        :param url: 

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ExternalDocumentation
        '''
        if __debug__:
            def stub(
                *,
                description: typing.Optional[builtins.str] = None,
                url: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument description", value=description, expected_type=type_hints["description"])
            check_type(argname="argument url", value=url, expected_type=type_hints["url"])
        self._values: typing.Dict[str, typing.Any] = {}
        if description is not None:
            self._values["description"] = description
        if url is not None:
            self._values["url"] = url

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ExternalDocumentation#description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def url(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ExternalDocumentation#url
        '''
        result = self._values.get("url")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ExternalDocumentation(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ExternalMetricSourceV2",
    jsii_struct_bases=[],
    name_mapping={"metric": "metric", "target": "target"},
)
class ExternalMetricSourceV2:
    def __init__(
        self,
        *,
        metric: typing.Union["MetricIdentifierV2", typing.Dict[str, typing.Any]],
        target: typing.Union["MetricTargetV2", typing.Dict[str, typing.Any]],
    ) -> None:
        '''ExternalMetricSource indicates how to scale on a metric not associated with any Kubernetes object (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).

        :param metric: metric identifies the target metric by name and selector.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ExternalMetricSource
        '''
        if isinstance(metric, dict):
            metric = MetricIdentifierV2(**metric)
        if isinstance(target, dict):
            target = MetricTargetV2(**target)
        if __debug__:
            def stub(
                *,
                metric: typing.Union[MetricIdentifierV2, typing.Dict[str, typing.Any]],
                target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric", value=metric, expected_type=type_hints["metric"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric": metric,
            "target": target,
        }

    @builtins.property
    def metric(self) -> "MetricIdentifierV2":
        '''metric identifies the target metric by name and selector.

        :schema: io.k8s.api.autoscaling.v2.ExternalMetricSource#metric
        '''
        result = self._values.get("metric")
        assert result is not None, "Required property 'metric' is missing"
        return typing.cast("MetricIdentifierV2", result)

    @builtins.property
    def target(self) -> "MetricTargetV2":
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ExternalMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast("MetricTargetV2", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ExternalMetricSourceV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ExternalMetricSourceV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "metric_name": "metricName",
        "metric_selector": "metricSelector",
        "target_average_value": "targetAverageValue",
        "target_value": "targetValue",
    },
)
class ExternalMetricSourceV2Beta1:
    def __init__(
        self,
        *,
        metric_name: builtins.str,
        metric_selector: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
        target_average_value: typing.Optional["Quantity"] = None,
        target_value: typing.Optional["Quantity"] = None,
    ) -> None:
        '''ExternalMetricSource indicates how to scale on a metric not associated with any Kubernetes object (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).

        Exactly one "target" type should be set.

        :param metric_name: metricName is the name of the metric in question.
        :param metric_selector: metricSelector is used to identify a specific time series within a given metric.
        :param target_average_value: targetAverageValue is the target per-pod value of global metric (as a quantity). Mutually exclusive with TargetValue.
        :param target_value: targetValue is the target value of the metric (as a quantity). Mutually exclusive with TargetAverageValue.

        :schema: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource
        '''
        if isinstance(metric_selector, dict):
            metric_selector = LabelSelector(**metric_selector)
        if __debug__:
            def stub(
                *,
                metric_name: builtins.str,
                metric_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                target_average_value: typing.Optional[Quantity] = None,
                target_value: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric_name", value=metric_name, expected_type=type_hints["metric_name"])
            check_type(argname="argument metric_selector", value=metric_selector, expected_type=type_hints["metric_selector"])
            check_type(argname="argument target_average_value", value=target_average_value, expected_type=type_hints["target_average_value"])
            check_type(argname="argument target_value", value=target_value, expected_type=type_hints["target_value"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric_name": metric_name,
        }
        if metric_selector is not None:
            self._values["metric_selector"] = metric_selector
        if target_average_value is not None:
            self._values["target_average_value"] = target_average_value
        if target_value is not None:
            self._values["target_value"] = target_value

    @builtins.property
    def metric_name(self) -> builtins.str:
        '''metricName is the name of the metric in question.

        :schema: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource#metricName
        '''
        result = self._values.get("metric_name")
        assert result is not None, "Required property 'metric_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def metric_selector(self) -> typing.Optional["LabelSelector"]:
        '''metricSelector is used to identify a specific time series within a given metric.

        :schema: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource#metricSelector
        '''
        result = self._values.get("metric_selector")
        return typing.cast(typing.Optional["LabelSelector"], result)

    @builtins.property
    def target_average_value(self) -> typing.Optional["Quantity"]:
        '''targetAverageValue is the target per-pod value of global metric (as a quantity).

        Mutually exclusive with TargetValue.

        :schema: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource#targetAverageValue
        '''
        result = self._values.get("target_average_value")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def target_value(self) -> typing.Optional["Quantity"]:
        '''targetValue is the target value of the metric (as a quantity).

        Mutually exclusive with TargetAverageValue.

        :schema: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource#targetValue
        '''
        result = self._values.get("target_value")
        return typing.cast(typing.Optional["Quantity"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ExternalMetricSourceV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ExternalMetricSourceV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"metric": "metric", "target": "target"},
)
class ExternalMetricSourceV2Beta2:
    def __init__(
        self,
        *,
        metric: typing.Union["MetricIdentifierV2Beta2", typing.Dict[str, typing.Any]],
        target: typing.Union["MetricTargetV2Beta2", typing.Dict[str, typing.Any]],
    ) -> None:
        '''ExternalMetricSource indicates how to scale on a metric not associated with any Kubernetes object (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).

        :param metric: metric identifies the target metric by name and selector.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ExternalMetricSource
        '''
        if isinstance(metric, dict):
            metric = MetricIdentifierV2Beta2(**metric)
        if isinstance(target, dict):
            target = MetricTargetV2Beta2(**target)
        if __debug__:
            def stub(
                *,
                metric: typing.Union[MetricIdentifierV2Beta2, typing.Dict[str, typing.Any]],
                target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric", value=metric, expected_type=type_hints["metric"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric": metric,
            "target": target,
        }

    @builtins.property
    def metric(self) -> "MetricIdentifierV2Beta2":
        '''metric identifies the target metric by name and selector.

        :schema: io.k8s.api.autoscaling.v2beta2.ExternalMetricSource#metric
        '''
        result = self._values.get("metric")
        assert result is not None, "Required property 'metric' is missing"
        return typing.cast("MetricIdentifierV2Beta2", result)

    @builtins.property
    def target(self) -> "MetricTargetV2Beta2":
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ExternalMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast("MetricTargetV2Beta2", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ExternalMetricSourceV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FcVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "fs_type": "fsType",
        "lun": "lun",
        "read_only": "readOnly",
        "target_ww_ns": "targetWwNs",
        "wwids": "wwids",
    },
)
class FcVolumeSource:
    def __init__(
        self,
        *,
        fs_type: typing.Optional[builtins.str] = None,
        lun: typing.Optional[jsii.Number] = None,
        read_only: typing.Optional[builtins.bool] = None,
        target_ww_ns: typing.Optional[typing.Sequence[builtins.str]] = None,
        wwids: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''Represents a Fibre Channel volume.

        Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.

        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
        :param lun: Optional: FC target lun number.
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param target_ww_ns: Optional: FC target worldwide names (WWNs).
        :param wwids: Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.

        :schema: io.k8s.api.core.v1.FCVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                fs_type: typing.Optional[builtins.str] = None,
                lun: typing.Optional[jsii.Number] = None,
                read_only: typing.Optional[builtins.bool] = None,
                target_ww_ns: typing.Optional[typing.Sequence[builtins.str]] = None,
                wwids: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument lun", value=lun, expected_type=type_hints["lun"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument target_ww_ns", value=target_ww_ns, expected_type=type_hints["target_ww_ns"])
            check_type(argname="argument wwids", value=wwids, expected_type=type_hints["wwids"])
        self._values: typing.Dict[str, typing.Any] = {}
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if lun is not None:
            self._values["lun"] = lun
        if read_only is not None:
            self._values["read_only"] = read_only
        if target_ww_ns is not None:
            self._values["target_ww_ns"] = target_ww_ns
        if wwids is not None:
            self._values["wwids"] = wwids

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.FCVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def lun(self) -> typing.Optional[jsii.Number]:
        '''Optional: FC target lun number.

        :schema: io.k8s.api.core.v1.FCVolumeSource#lun
        '''
        result = self._values.get("lun")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.FCVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def target_ww_ns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Optional: FC target worldwide names (WWNs).

        :schema: io.k8s.api.core.v1.FCVolumeSource#targetWWNs
        '''
        result = self._values.get("target_ww_ns")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def wwids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.

        :schema: io.k8s.api.core.v1.FCVolumeSource#wwids
        '''
        result = self._values.get("wwids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FcVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlexPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "driver": "driver",
        "fs_type": "fsType",
        "options": "options",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
    },
)
class FlexPersistentVolumeSource:
    def __init__(
        self,
        *,
        driver: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        options: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''FlexPersistentVolumeSource represents a generic persistent volume resource that is provisioned/attached using an exec based plugin.

        :param driver: Driver is the name of the driver to use for this volume.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script.
        :param options: Optional: Extra command options if any.
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param secret_ref: Optional: SecretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.

        :schema: io.k8s.api.core.v1.FlexPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = SecretReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                driver: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                options: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument driver", value=driver, expected_type=type_hints["driver"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument options", value=options, expected_type=type_hints["options"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "driver": driver,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if options is not None:
            self._values["options"] = options
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def driver(self) -> builtins.str:
        '''Driver is the name of the driver to use for this volume.

        :schema: io.k8s.api.core.v1.FlexPersistentVolumeSource#driver
        '''
        result = self._values.get("driver")
        assert result is not None, "Required property 'driver' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script.

        :schema: io.k8s.api.core.v1.FlexPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def options(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Optional: Extra command options if any.

        :schema: io.k8s.api.core.v1.FlexPersistentVolumeSource#options
        '''
        result = self._values.get("options")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.FlexPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["SecretReference"]:
        '''Optional: SecretRef is reference to the secret object containing sensitive information to pass to the plugin scripts.

        This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.

        :schema: io.k8s.api.core.v1.FlexPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlexPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlexVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "driver": "driver",
        "fs_type": "fsType",
        "options": "options",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
    },
)
class FlexVolumeSource:
    def __init__(
        self,
        *,
        driver: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        options: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.

        :param driver: Driver is the name of the driver to use for this volume.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script.
        :param options: Optional: Extra command options if any.
        :param read_only: Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param secret_ref: Optional: SecretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.

        :schema: io.k8s.api.core.v1.FlexVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                driver: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                options: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument driver", value=driver, expected_type=type_hints["driver"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument options", value=options, expected_type=type_hints["options"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "driver": driver,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if options is not None:
            self._values["options"] = options
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def driver(self) -> builtins.str:
        '''Driver is the name of the driver to use for this volume.

        :schema: io.k8s.api.core.v1.FlexVolumeSource#driver
        '''
        result = self._values.get("driver")
        assert result is not None, "Required property 'driver' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script.

        :schema: io.k8s.api.core.v1.FlexVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def options(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Optional: Extra command options if any.

        :schema: io.k8s.api.core.v1.FlexVolumeSource#options
        '''
        result = self._values.get("options")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Optional: Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.FlexVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["LocalObjectReference"]:
        '''Optional: SecretRef is reference to the secret object containing sensitive information to pass to the plugin scripts.

        This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.

        :schema: io.k8s.api.core.v1.FlexVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["LocalObjectReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlexVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlockerVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"dataset_name": "datasetName", "dataset_uuid": "datasetUuid"},
)
class FlockerVolumeSource:
    def __init__(
        self,
        *,
        dataset_name: typing.Optional[builtins.str] = None,
        dataset_uuid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Flocker volume mounted by the Flocker agent.

        One and only one of datasetName and datasetUUID should be set. Flocker volumes do not support ownership management or SELinux relabeling.

        :param dataset_name: Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated.
        :param dataset_uuid: UUID of the dataset. This is unique identifier of a Flocker dataset

        :schema: io.k8s.api.core.v1.FlockerVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                dataset_name: typing.Optional[builtins.str] = None,
                dataset_uuid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument dataset_name", value=dataset_name, expected_type=type_hints["dataset_name"])
            check_type(argname="argument dataset_uuid", value=dataset_uuid, expected_type=type_hints["dataset_uuid"])
        self._values: typing.Dict[str, typing.Any] = {}
        if dataset_name is not None:
            self._values["dataset_name"] = dataset_name
        if dataset_uuid is not None:
            self._values["dataset_uuid"] = dataset_uuid

    @builtins.property
    def dataset_name(self) -> typing.Optional[builtins.str]:
        '''Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated.

        :schema: io.k8s.api.core.v1.FlockerVolumeSource#datasetName
        '''
        result = self._values.get("dataset_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def dataset_uuid(self) -> typing.Optional[builtins.str]:
        '''UUID of the dataset.

        This is unique identifier of a Flocker dataset

        :schema: io.k8s.api.core.v1.FlockerVolumeSource#datasetUUID
        '''
        result = self._values.get("dataset_uuid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlockerVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlowDistinguisherMethodV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"type": "type"},
)
class FlowDistinguisherMethodV1Beta1:
    def __init__(self, *, type: builtins.str) -> None:
        '''FlowDistinguisherMethod specifies the method of a flow distinguisher.

        :param type: ``type`` is the type of flow distinguisher method The supported types are "ByUser" and "ByNamespace". Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod
        '''
        if __debug__:
            def stub(*, type: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }

    @builtins.property
    def type(self) -> builtins.str:
        '''``type`` is the type of flow distinguisher method The supported types are "ByUser" and "ByNamespace".

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowDistinguisherMethodV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlowDistinguisherMethodV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"type": "type"},
)
class FlowDistinguisherMethodV1Beta2:
    def __init__(self, *, type: builtins.str) -> None:
        '''FlowDistinguisherMethod specifies the method of a flow distinguisher.

        :param type: ``type`` is the type of flow distinguisher method The supported types are "ByUser" and "ByNamespace". Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod
        '''
        if __debug__:
            def stub(*, type: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }

    @builtins.property
    def type(self) -> builtins.str:
        '''``type`` is the type of flow distinguisher method The supported types are "ByUser" and "ByNamespace".

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowDistinguisherMethodV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlowSchemaSpecV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "priority_level_configuration": "priorityLevelConfiguration",
        "distinguisher_method": "distinguisherMethod",
        "matching_precedence": "matchingPrecedence",
        "rules": "rules",
    },
)
class FlowSchemaSpecV1Beta1:
    def __init__(
        self,
        *,
        priority_level_configuration: typing.Union["PriorityLevelConfigurationReferenceV1Beta1", typing.Dict[str, typing.Any]],
        distinguisher_method: typing.Optional[typing.Union[FlowDistinguisherMethodV1Beta1, typing.Dict[str, typing.Any]]] = None,
        matching_precedence: typing.Optional[jsii.Number] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRulesWithSubjectsV1Beta1", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''FlowSchemaSpec describes how the FlowSchema's specification looks like.

        :param priority_level_configuration: ``priorityLevelConfiguration`` should reference a PriorityLevelConfiguration in the cluster. If the reference cannot be resolved, the FlowSchema will be ignored and marked as invalid in its status. Required.
        :param distinguisher_method: ``distinguisherMethod`` defines how to compute the flow distinguisher for requests that match this schema. ``nil`` specifies that the distinguisher is disabled and thus will always be the empty string.
        :param matching_precedence: ``matchingPrecedence`` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.
        :param rules: ``rules`` describes which requests will match this flow schema. This FlowSchema matches a request if and only if at least one member of rules matches the request. if it is an empty slice, there will be no requests matching the FlowSchema.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec
        '''
        if isinstance(priority_level_configuration, dict):
            priority_level_configuration = PriorityLevelConfigurationReferenceV1Beta1(**priority_level_configuration)
        if isinstance(distinguisher_method, dict):
            distinguisher_method = FlowDistinguisherMethodV1Beta1(**distinguisher_method)
        if __debug__:
            def stub(
                *,
                priority_level_configuration: typing.Union[PriorityLevelConfigurationReferenceV1Beta1, typing.Dict[str, typing.Any]],
                distinguisher_method: typing.Optional[typing.Union[FlowDistinguisherMethodV1Beta1, typing.Dict[str, typing.Any]]] = None,
                matching_precedence: typing.Optional[jsii.Number] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[PolicyRulesWithSubjectsV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument priority_level_configuration", value=priority_level_configuration, expected_type=type_hints["priority_level_configuration"])
            check_type(argname="argument distinguisher_method", value=distinguisher_method, expected_type=type_hints["distinguisher_method"])
            check_type(argname="argument matching_precedence", value=matching_precedence, expected_type=type_hints["matching_precedence"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
        self._values: typing.Dict[str, typing.Any] = {
            "priority_level_configuration": priority_level_configuration,
        }
        if distinguisher_method is not None:
            self._values["distinguisher_method"] = distinguisher_method
        if matching_precedence is not None:
            self._values["matching_precedence"] = matching_precedence
        if rules is not None:
            self._values["rules"] = rules

    @builtins.property
    def priority_level_configuration(
        self,
    ) -> "PriorityLevelConfigurationReferenceV1Beta1":
        '''``priorityLevelConfiguration`` should reference a PriorityLevelConfiguration in the cluster.

        If the reference cannot be resolved, the FlowSchema will be ignored and marked as invalid in its status. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec#priorityLevelConfiguration
        '''
        result = self._values.get("priority_level_configuration")
        assert result is not None, "Required property 'priority_level_configuration' is missing"
        return typing.cast("PriorityLevelConfigurationReferenceV1Beta1", result)

    @builtins.property
    def distinguisher_method(self) -> typing.Optional[FlowDistinguisherMethodV1Beta1]:
        '''``distinguisherMethod`` defines how to compute the flow distinguisher for requests that match this schema.

        ``nil`` specifies that the distinguisher is disabled and thus will always be the empty string.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec#distinguisherMethod
        '''
        result = self._values.get("distinguisher_method")
        return typing.cast(typing.Optional[FlowDistinguisherMethodV1Beta1], result)

    @builtins.property
    def matching_precedence(self) -> typing.Optional[jsii.Number]:
        '''``matchingPrecedence`` is used to choose among the FlowSchemas that match a given request.

        The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence.  Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec#matchingPrecedence
        '''
        result = self._values.get("matching_precedence")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List["PolicyRulesWithSubjectsV1Beta1"]]:
        '''``rules`` describes which requests will match this flow schema.

        This FlowSchema matches a request if and only if at least one member of rules matches the request. if it is an empty slice, there will be no requests matching the FlowSchema.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List["PolicyRulesWithSubjectsV1Beta1"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowSchemaSpecV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FlowSchemaSpecV1Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "priority_level_configuration": "priorityLevelConfiguration",
        "distinguisher_method": "distinguisherMethod",
        "matching_precedence": "matchingPrecedence",
        "rules": "rules",
    },
)
class FlowSchemaSpecV1Beta2:
    def __init__(
        self,
        *,
        priority_level_configuration: typing.Union["PriorityLevelConfigurationReferenceV1Beta2", typing.Dict[str, typing.Any]],
        distinguisher_method: typing.Optional[typing.Union[FlowDistinguisherMethodV1Beta2, typing.Dict[str, typing.Any]]] = None,
        matching_precedence: typing.Optional[jsii.Number] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRulesWithSubjectsV1Beta2", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''FlowSchemaSpec describes how the FlowSchema's specification looks like.

        :param priority_level_configuration: ``priorityLevelConfiguration`` should reference a PriorityLevelConfiguration in the cluster. If the reference cannot be resolved, the FlowSchema will be ignored and marked as invalid in its status. Required.
        :param distinguisher_method: ``distinguisherMethod`` defines how to compute the flow distinguisher for requests that match this schema. ``nil`` specifies that the distinguisher is disabled and thus will always be the empty string.
        :param matching_precedence: ``matchingPrecedence`` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.
        :param rules: ``rules`` describes which requests will match this flow schema. This FlowSchema matches a request if and only if at least one member of rules matches the request. if it is an empty slice, there will be no requests matching the FlowSchema.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec
        '''
        if isinstance(priority_level_configuration, dict):
            priority_level_configuration = PriorityLevelConfigurationReferenceV1Beta2(**priority_level_configuration)
        if isinstance(distinguisher_method, dict):
            distinguisher_method = FlowDistinguisherMethodV1Beta2(**distinguisher_method)
        if __debug__:
            def stub(
                *,
                priority_level_configuration: typing.Union[PriorityLevelConfigurationReferenceV1Beta2, typing.Dict[str, typing.Any]],
                distinguisher_method: typing.Optional[typing.Union[FlowDistinguisherMethodV1Beta2, typing.Dict[str, typing.Any]]] = None,
                matching_precedence: typing.Optional[jsii.Number] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[PolicyRulesWithSubjectsV1Beta2, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument priority_level_configuration", value=priority_level_configuration, expected_type=type_hints["priority_level_configuration"])
            check_type(argname="argument distinguisher_method", value=distinguisher_method, expected_type=type_hints["distinguisher_method"])
            check_type(argname="argument matching_precedence", value=matching_precedence, expected_type=type_hints["matching_precedence"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
        self._values: typing.Dict[str, typing.Any] = {
            "priority_level_configuration": priority_level_configuration,
        }
        if distinguisher_method is not None:
            self._values["distinguisher_method"] = distinguisher_method
        if matching_precedence is not None:
            self._values["matching_precedence"] = matching_precedence
        if rules is not None:
            self._values["rules"] = rules

    @builtins.property
    def priority_level_configuration(
        self,
    ) -> "PriorityLevelConfigurationReferenceV1Beta2":
        '''``priorityLevelConfiguration`` should reference a PriorityLevelConfiguration in the cluster.

        If the reference cannot be resolved, the FlowSchema will be ignored and marked as invalid in its status. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec#priorityLevelConfiguration
        '''
        result = self._values.get("priority_level_configuration")
        assert result is not None, "Required property 'priority_level_configuration' is missing"
        return typing.cast("PriorityLevelConfigurationReferenceV1Beta2", result)

    @builtins.property
    def distinguisher_method(self) -> typing.Optional[FlowDistinguisherMethodV1Beta2]:
        '''``distinguisherMethod`` defines how to compute the flow distinguisher for requests that match this schema.

        ``nil`` specifies that the distinguisher is disabled and thus will always be the empty string.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec#distinguisherMethod
        '''
        result = self._values.get("distinguisher_method")
        return typing.cast(typing.Optional[FlowDistinguisherMethodV1Beta2], result)

    @builtins.property
    def matching_precedence(self) -> typing.Optional[jsii.Number]:
        '''``matchingPrecedence`` is used to choose among the FlowSchemas that match a given request.

        The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence.  Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec#matchingPrecedence
        '''
        result = self._values.get("matching_precedence")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List["PolicyRulesWithSubjectsV1Beta2"]]:
        '''``rules`` describes which requests will match this flow schema.

        This FlowSchema matches a request if and only if at least one member of rules matches the request. if it is an empty slice, there will be no requests matching the FlowSchema.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List["PolicyRulesWithSubjectsV1Beta2"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowSchemaSpecV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ForZone",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class ForZone:
    def __init__(self, *, name: builtins.str) -> None:
        '''ForZone provides information about which zones should consume this endpoint.

        :param name: name represents the name of the zone.

        :schema: io.k8s.api.discovery.v1.ForZone
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''name represents the name of the zone.

        :schema: io.k8s.api.discovery.v1.ForZone#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ForZone(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ForZoneV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class ForZoneV1Beta1:
    def __init__(self, *, name: builtins.str) -> None:
        '''ForZone provides information about which zones should consume this endpoint.

        :param name: name represents the name of the zone.

        :schema: io.k8s.api.discovery.v1beta1.ForZone
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''name represents the name of the zone.

        :schema: io.k8s.api.discovery.v1beta1.ForZone#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ForZoneV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.FsGroupStrategyOptionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"ranges": "ranges", "rule": "rule"},
)
class FsGroupStrategyOptionsV1Beta1:
    def __init__(
        self,
        *,
        ranges: typing.Optional[typing.Sequence[typing.Union["IdRangeV1Beta1", typing.Dict[str, typing.Any]]]] = None,
        rule: typing.Optional[builtins.str] = None,
    ) -> None:
        '''FSGroupStrategyOptions defines the strategy type and options used to create the strategy.

        :param ranges: ranges are the allowed ranges of fs groups. If you would like to force a single fs group then supply a single range with the same start and end. Required for MustRunAs.
        :param rule: rule is the strategy that will dictate what FSGroup is used in the SecurityContext.

        :schema: io.k8s.api.policy.v1beta1.FSGroupStrategyOptions
        '''
        if __debug__:
            def stub(
                *,
                ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                rule: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ranges", value=ranges, expected_type=type_hints["ranges"])
            check_type(argname="argument rule", value=rule, expected_type=type_hints["rule"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ranges is not None:
            self._values["ranges"] = ranges
        if rule is not None:
            self._values["rule"] = rule

    @builtins.property
    def ranges(self) -> typing.Optional[typing.List["IdRangeV1Beta1"]]:
        '''ranges are the allowed ranges of fs groups.

        If you would like to force a single fs group then supply a single range with the same start and end. Required for MustRunAs.

        :schema: io.k8s.api.policy.v1beta1.FSGroupStrategyOptions#ranges
        '''
        result = self._values.get("ranges")
        return typing.cast(typing.Optional[typing.List["IdRangeV1Beta1"]], result)

    @builtins.property
    def rule(self) -> typing.Optional[builtins.str]:
        '''rule is the strategy that will dictate what FSGroup is used in the SecurityContext.

        :schema: io.k8s.api.policy.v1beta1.FSGroupStrategyOptions#rule
        '''
        result = self._values.get("rule")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FsGroupStrategyOptionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GcePersistentDiskVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "pd_name": "pdName",
        "fs_type": "fsType",
        "partition": "partition",
        "read_only": "readOnly",
    },
)
class GcePersistentDiskVolumeSource:
    def __init__(
        self,
        *,
        pd_name: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        partition: typing.Optional[jsii.Number] = None,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Represents a Persistent Disk resource in Google Compute Engine.

        A GCE PD must exist before mounting to a container. The disk must also be in the same GCE project and zone as the kubelet. A GCE PD can only be mounted as read/write once or read-only many times. GCE PDs support ownership management and SELinux relabeling.

        :param pd_name: Unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
        :param fs_type: Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
        :param partition: The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
        :param read_only: ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk Default: false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.GCEPersistentDiskVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                pd_name: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                partition: typing.Optional[jsii.Number] = None,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pd_name", value=pd_name, expected_type=type_hints["pd_name"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument partition", value=partition, expected_type=type_hints["partition"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "pd_name": pd_name,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if partition is not None:
            self._values["partition"] = partition
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def pd_name(self) -> builtins.str:
        '''Unique name of the PD resource in GCE.

        Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.GCEPersistentDiskVolumeSource#pdName
        '''
        result = self._values.get("pd_name")
        assert result is not None, "Required property 'pd_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type of the volume that you want to mount.

        Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.GCEPersistentDiskVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def partition(self) -> typing.Optional[jsii.Number]:
        '''The partition in the volume that you want to mount.

        If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.GCEPersistentDiskVolumeSource#partition
        '''
        result = self._values.get("partition")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the ReadOnly setting in VolumeMounts.

        Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :default: false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.GCEPersistentDiskVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GcePersistentDiskVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GitRepoVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "repository": "repository",
        "directory": "directory",
        "revision": "revision",
    },
)
class GitRepoVolumeSource:
    def __init__(
        self,
        *,
        repository: builtins.str,
        directory: typing.Optional[builtins.str] = None,
        revision: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a volume that is populated with the contents of a git repository.

        Git repo volumes do not support ownership management. Git repo volumes support SELinux relabeling.

        DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod's container.

        :param repository: Repository URL.
        :param directory: Target directory name. Must not contain or start with '..'. If '.' is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name.
        :param revision: Commit hash for the specified revision.

        :schema: io.k8s.api.core.v1.GitRepoVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                repository: builtins.str,
                directory: typing.Optional[builtins.str] = None,
                revision: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument repository", value=repository, expected_type=type_hints["repository"])
            check_type(argname="argument directory", value=directory, expected_type=type_hints["directory"])
            check_type(argname="argument revision", value=revision, expected_type=type_hints["revision"])
        self._values: typing.Dict[str, typing.Any] = {
            "repository": repository,
        }
        if directory is not None:
            self._values["directory"] = directory
        if revision is not None:
            self._values["revision"] = revision

    @builtins.property
    def repository(self) -> builtins.str:
        '''Repository URL.

        :schema: io.k8s.api.core.v1.GitRepoVolumeSource#repository
        '''
        result = self._values.get("repository")
        assert result is not None, "Required property 'repository' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def directory(self) -> typing.Optional[builtins.str]:
        '''Target directory name.

        Must not contain or start with '..'.  If '.' is supplied, the volume directory will be the git repository.  Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name.

        :schema: io.k8s.api.core.v1.GitRepoVolumeSource#directory
        '''
        result = self._values.get("directory")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def revision(self) -> typing.Optional[builtins.str]:
        '''Commit hash for the specified revision.

        :schema: io.k8s.api.core.v1.GitRepoVolumeSource#revision
        '''
        result = self._values.get("revision")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GitRepoVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GlusterfsPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "endpoints": "endpoints",
        "path": "path",
        "endpoints_namespace": "endpointsNamespace",
        "read_only": "readOnly",
    },
)
class GlusterfsPersistentVolumeSource:
    def __init__(
        self,
        *,
        endpoints: builtins.str,
        path: builtins.str,
        endpoints_namespace: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Represents a Glusterfs mount that lasts the lifetime of a pod.

        Glusterfs volumes do not support ownership management or SELinux relabeling.

        :param endpoints: EndpointsName is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
        :param path: Path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
        :param endpoints_namespace: EndpointsNamespace is the namespace that contains Glusterfs endpoint. If this field is empty, the EndpointNamespace defaults to the same namespace as the bound PVC. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
        :param read_only: ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod Default: false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsPersistentVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                endpoints: builtins.str,
                path: builtins.str,
                endpoints_namespace: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument endpoints", value=endpoints, expected_type=type_hints["endpoints"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument endpoints_namespace", value=endpoints_namespace, expected_type=type_hints["endpoints_namespace"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "endpoints": endpoints,
            "path": path,
        }
        if endpoints_namespace is not None:
            self._values["endpoints_namespace"] = endpoints_namespace
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def endpoints(self) -> builtins.str:
        '''EndpointsName is the endpoint name that details Glusterfs topology.

        More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsPersistentVolumeSource#endpoints
        '''
        result = self._values.get("endpoints")
        assert result is not None, "Required property 'endpoints' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def path(self) -> builtins.str:
        '''Path is the Glusterfs volume path.

        More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsPersistentVolumeSource#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def endpoints_namespace(self) -> typing.Optional[builtins.str]:
        '''EndpointsNamespace is the namespace that contains Glusterfs endpoint.

        If this field is empty, the EndpointNamespace defaults to the same namespace as the bound PVC. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsPersistentVolumeSource#endpointsNamespace
        '''
        result = self._values.get("endpoints_namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions.

        Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :default: false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GlusterfsPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GlusterfsVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"endpoints": "endpoints", "path": "path", "read_only": "readOnly"},
)
class GlusterfsVolumeSource:
    def __init__(
        self,
        *,
        endpoints: builtins.str,
        path: builtins.str,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Represents a Glusterfs mount that lasts the lifetime of a pod.

        Glusterfs volumes do not support ownership management or SELinux relabeling.

        :param endpoints: EndpointsName is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
        :param path: Path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
        :param read_only: ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod Default: false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                endpoints: builtins.str,
                path: builtins.str,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument endpoints", value=endpoints, expected_type=type_hints["endpoints"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "endpoints": endpoints,
            "path": path,
        }
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def endpoints(self) -> builtins.str:
        '''EndpointsName is the endpoint name that details Glusterfs topology.

        More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsVolumeSource#endpoints
        '''
        result = self._values.get("endpoints")
        assert result is not None, "Required property 'endpoints' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def path(self) -> builtins.str:
        '''Path is the Glusterfs volume path.

        More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsVolumeSource#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions.

        Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :default: false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

        :schema: io.k8s.api.core.v1.GlusterfsVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GlusterfsVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GroupSubjectV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class GroupSubjectV1Beta1:
    def __init__(self, *, name: builtins.str) -> None:
        '''GroupSubject holds detailed information for group-kind subject.

        :param name: name is the user group that matches, or "*" to match all user groups. See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some well-known group names. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.GroupSubject
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the user group that matches, or "*" to match all user groups.

        See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some well-known group names. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.GroupSubject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GroupSubjectV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GroupSubjectV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class GroupSubjectV1Beta2:
    def __init__(self, *, name: builtins.str) -> None:
        '''GroupSubject holds detailed information for group-kind subject.

        :param name: name is the user group that matches, or "*" to match all user groups. See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some well-known group names. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.GroupSubject
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the user group that matches, or "*" to match all user groups.

        See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some well-known group names. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.GroupSubject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GroupSubjectV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.GrpcAction",
    jsii_struct_bases=[],
    name_mapping={"port": "port", "service": "service"},
)
class GrpcAction:
    def __init__(
        self,
        *,
        port: jsii.Number,
        service: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param port: Port number of the gRPC service. Number must be in the range 1 to 65535.
        :param service: Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). If this is not specified, the default behavior is defined by gRPC.

        :schema: io.k8s.api.core.v1.GRPCAction
        '''
        if __debug__:
            def stub(
                *,
                port: jsii.Number,
                service: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument service", value=service, expected_type=type_hints["service"])
        self._values: typing.Dict[str, typing.Any] = {
            "port": port,
        }
        if service is not None:
            self._values["service"] = service

    @builtins.property
    def port(self) -> jsii.Number:
        '''Port number of the gRPC service.

        Number must be in the range 1 to 65535.

        :schema: io.k8s.api.core.v1.GRPCAction#port
        '''
        result = self._values.get("port")
        assert result is not None, "Required property 'port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def service(self) -> typing.Optional[builtins.str]:
        '''Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).

        If this is not specified, the default behavior is defined by gRPC.

        :schema: io.k8s.api.core.v1.GRPCAction#service
        '''
        result = self._values.get("service")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcAction(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HorizontalPodAutoscalerBehaviorV2",
    jsii_struct_bases=[],
    name_mapping={"scale_down": "scaleDown", "scale_up": "scaleUp"},
)
class HorizontalPodAutoscalerBehaviorV2:
    def __init__(
        self,
        *,
        scale_down: typing.Optional[typing.Union["HpaScalingRulesV2", typing.Dict[str, typing.Any]]] = None,
        scale_up: typing.Optional[typing.Union["HpaScalingRulesV2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscalerBehavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively).

        :param scale_down: 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).
        :param scale_up: scaleUp is scaling policy for scaling Up. If not set, the default value is the higher of: - increase no more than 4 pods per 60 seconds - double the number of pods per 60 seconds No stabilization is used.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerBehavior
        '''
        if isinstance(scale_down, dict):
            scale_down = HpaScalingRulesV2(**scale_down)
        if isinstance(scale_up, dict):
            scale_up = HpaScalingRulesV2(**scale_up)
        if __debug__:
            def stub(
                *,
                scale_down: typing.Optional[typing.Union[HpaScalingRulesV2, typing.Dict[str, typing.Any]]] = None,
                scale_up: typing.Optional[typing.Union[HpaScalingRulesV2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scale_down", value=scale_down, expected_type=type_hints["scale_down"])
            check_type(argname="argument scale_up", value=scale_up, expected_type=type_hints["scale_up"])
        self._values: typing.Dict[str, typing.Any] = {}
        if scale_down is not None:
            self._values["scale_down"] = scale_down
        if scale_up is not None:
            self._values["scale_up"] = scale_up

    @builtins.property
    def scale_down(self) -> typing.Optional["HpaScalingRulesV2"]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerBehavior#scaleDown
        '''
        result = self._values.get("scale_down")
        return typing.cast(typing.Optional["HpaScalingRulesV2"], result)

    @builtins.property
    def scale_up(self) -> typing.Optional["HpaScalingRulesV2"]:
        '''scaleUp is scaling policy for scaling Up.

        If not set, the default value is the higher of:

        - increase no more than 4 pods per 60 seconds
        - double the number of pods per 60 seconds
          No stabilization is used.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerBehavior#scaleUp
        '''
        result = self._values.get("scale_up")
        return typing.cast(typing.Optional["HpaScalingRulesV2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HorizontalPodAutoscalerBehaviorV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HorizontalPodAutoscalerBehaviorV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"scale_down": "scaleDown", "scale_up": "scaleUp"},
)
class HorizontalPodAutoscalerBehaviorV2Beta2:
    def __init__(
        self,
        *,
        scale_down: typing.Optional[typing.Union["HpaScalingRulesV2Beta2", typing.Dict[str, typing.Any]]] = None,
        scale_up: typing.Optional[typing.Union["HpaScalingRulesV2Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscalerBehavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively).

        :param scale_down: 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).
        :param scale_up: scaleUp is scaling policy for scaling Up. If not set, the default value is the higher of: - increase no more than 4 pods per 60 seconds - double the number of pods per 60 seconds No stabilization is used.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior
        '''
        if isinstance(scale_down, dict):
            scale_down = HpaScalingRulesV2Beta2(**scale_down)
        if isinstance(scale_up, dict):
            scale_up = HpaScalingRulesV2Beta2(**scale_up)
        if __debug__:
            def stub(
                *,
                scale_down: typing.Optional[typing.Union[HpaScalingRulesV2Beta2, typing.Dict[str, typing.Any]]] = None,
                scale_up: typing.Optional[typing.Union[HpaScalingRulesV2Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scale_down", value=scale_down, expected_type=type_hints["scale_down"])
            check_type(argname="argument scale_up", value=scale_up, expected_type=type_hints["scale_up"])
        self._values: typing.Dict[str, typing.Any] = {}
        if scale_down is not None:
            self._values["scale_down"] = scale_down
        if scale_up is not None:
            self._values["scale_up"] = scale_up

    @builtins.property
    def scale_down(self) -> typing.Optional["HpaScalingRulesV2Beta2"]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior#scaleDown
        '''
        result = self._values.get("scale_down")
        return typing.cast(typing.Optional["HpaScalingRulesV2Beta2"], result)

    @builtins.property
    def scale_up(self) -> typing.Optional["HpaScalingRulesV2Beta2"]:
        '''scaleUp is scaling policy for scaling Up.

        If not set, the default value is the higher of:

        - increase no more than 4 pods per 60 seconds
        - double the number of pods per 60 seconds
          No stabilization is used.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior#scaleUp
        '''
        result = self._values.get("scale_up")
        return typing.cast(typing.Optional["HpaScalingRulesV2Beta2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HorizontalPodAutoscalerBehaviorV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HorizontalPodAutoscalerSpec",
    jsii_struct_bases=[],
    name_mapping={
        "max_replicas": "maxReplicas",
        "scale_target_ref": "scaleTargetRef",
        "min_replicas": "minReplicas",
        "target_cpu_utilization_percentage": "targetCpuUtilizationPercentage",
    },
)
class HorizontalPodAutoscalerSpec:
    def __init__(
        self,
        *,
        max_replicas: jsii.Number,
        scale_target_ref: typing.Union[CrossVersionObjectReference, typing.Dict[str, typing.Any]],
        min_replicas: typing.Optional[jsii.Number] = None,
        target_cpu_utilization_percentage: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''specification of a horizontal pod autoscaler.

        :param max_replicas: upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.
        :param scale_target_ref: reference to scaled resource; horizontal pod autoscaler will learn the current resource consumption and will set the desired number of pods by using its Scale subresource.
        :param min_replicas: 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.
        :param target_cpu_utilization_percentage: target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified the default autoscaling policy will be used.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerSpec
        '''
        if isinstance(scale_target_ref, dict):
            scale_target_ref = CrossVersionObjectReference(**scale_target_ref)
        if __debug__:
            def stub(
                *,
                max_replicas: jsii.Number,
                scale_target_ref: typing.Union[CrossVersionObjectReference, typing.Dict[str, typing.Any]],
                min_replicas: typing.Optional[jsii.Number] = None,
                target_cpu_utilization_percentage: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_replicas", value=max_replicas, expected_type=type_hints["max_replicas"])
            check_type(argname="argument scale_target_ref", value=scale_target_ref, expected_type=type_hints["scale_target_ref"])
            check_type(argname="argument min_replicas", value=min_replicas, expected_type=type_hints["min_replicas"])
            check_type(argname="argument target_cpu_utilization_percentage", value=target_cpu_utilization_percentage, expected_type=type_hints["target_cpu_utilization_percentage"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_replicas": max_replicas,
            "scale_target_ref": scale_target_ref,
        }
        if min_replicas is not None:
            self._values["min_replicas"] = min_replicas
        if target_cpu_utilization_percentage is not None:
            self._values["target_cpu_utilization_percentage"] = target_cpu_utilization_percentage

    @builtins.property
    def max_replicas(self) -> jsii.Number:
        '''upper limit for the number of pods that can be set by the autoscaler;

        cannot be smaller than MinReplicas.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerSpec#maxReplicas
        '''
        result = self._values.get("max_replicas")
        assert result is not None, "Required property 'max_replicas' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def scale_target_ref(self) -> CrossVersionObjectReference:
        '''reference to scaled resource;

        horizontal pod autoscaler will learn the current resource consumption and will set the desired number of pods by using its Scale subresource.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerSpec#scaleTargetRef
        '''
        result = self._values.get("scale_target_ref")
        assert result is not None, "Required property 'scale_target_ref' is missing"
        return typing.cast(CrossVersionObjectReference, result)

    @builtins.property
    def min_replicas(self) -> typing.Optional[jsii.Number]:
        '''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.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerSpec#minReplicas
        '''
        result = self._values.get("min_replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def target_cpu_utilization_percentage(self) -> typing.Optional[jsii.Number]:
        '''target average CPU utilization (represented as a percentage of requested CPU) over all the pods;

        if not specified the default autoscaling policy will be used.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerSpec#targetCPUUtilizationPercentage
        '''
        result = self._values.get("target_cpu_utilization_percentage")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HorizontalPodAutoscalerSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HorizontalPodAutoscalerSpecV2",
    jsii_struct_bases=[],
    name_mapping={
        "max_replicas": "maxReplicas",
        "scale_target_ref": "scaleTargetRef",
        "behavior": "behavior",
        "metrics": "metrics",
        "min_replicas": "minReplicas",
    },
)
class HorizontalPodAutoscalerSpecV2:
    def __init__(
        self,
        *,
        max_replicas: jsii.Number,
        scale_target_ref: typing.Union[CrossVersionObjectReferenceV2, typing.Dict[str, typing.Any]],
        behavior: typing.Optional[typing.Union[HorizontalPodAutoscalerBehaviorV2, typing.Dict[str, typing.Any]]] = None,
        metrics: typing.Optional[typing.Sequence[typing.Union["MetricSpecV2", typing.Dict[str, typing.Any]]]] = None,
        min_replicas: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler.

        :param max_replicas: maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas.
        :param scale_target_ref: 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.
        :param behavior: 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.
        :param metrics: 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.
        :param min_replicas: 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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerSpec
        '''
        if isinstance(scale_target_ref, dict):
            scale_target_ref = CrossVersionObjectReferenceV2(**scale_target_ref)
        if isinstance(behavior, dict):
            behavior = HorizontalPodAutoscalerBehaviorV2(**behavior)
        if __debug__:
            def stub(
                *,
                max_replicas: jsii.Number,
                scale_target_ref: typing.Union[CrossVersionObjectReferenceV2, typing.Dict[str, typing.Any]],
                behavior: typing.Optional[typing.Union[HorizontalPodAutoscalerBehaviorV2, typing.Dict[str, typing.Any]]] = None,
                metrics: typing.Optional[typing.Sequence[typing.Union[MetricSpecV2, typing.Dict[str, typing.Any]]]] = None,
                min_replicas: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_replicas", value=max_replicas, expected_type=type_hints["max_replicas"])
            check_type(argname="argument scale_target_ref", value=scale_target_ref, expected_type=type_hints["scale_target_ref"])
            check_type(argname="argument behavior", value=behavior, expected_type=type_hints["behavior"])
            check_type(argname="argument metrics", value=metrics, expected_type=type_hints["metrics"])
            check_type(argname="argument min_replicas", value=min_replicas, expected_type=type_hints["min_replicas"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_replicas": max_replicas,
            "scale_target_ref": scale_target_ref,
        }
        if behavior is not None:
            self._values["behavior"] = behavior
        if metrics is not None:
            self._values["metrics"] = metrics
        if min_replicas is not None:
            self._values["min_replicas"] = min_replicas

    @builtins.property
    def max_replicas(self) -> jsii.Number:
        '''maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.

        It cannot be less that minReplicas.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerSpec#maxReplicas
        '''
        result = self._values.get("max_replicas")
        assert result is not None, "Required property 'max_replicas' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def scale_target_ref(self) -> CrossVersionObjectReferenceV2:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerSpec#scaleTargetRef
        '''
        result = self._values.get("scale_target_ref")
        assert result is not None, "Required property 'scale_target_ref' is missing"
        return typing.cast(CrossVersionObjectReferenceV2, result)

    @builtins.property
    def behavior(self) -> typing.Optional[HorizontalPodAutoscalerBehaviorV2]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerSpec#behavior
        '''
        result = self._values.get("behavior")
        return typing.cast(typing.Optional[HorizontalPodAutoscalerBehaviorV2], result)

    @builtins.property
    def metrics(self) -> typing.Optional[typing.List["MetricSpecV2"]]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerSpec#metrics
        '''
        result = self._values.get("metrics")
        return typing.cast(typing.Optional[typing.List["MetricSpecV2"]], result)

    @builtins.property
    def min_replicas(self) -> typing.Optional[jsii.Number]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerSpec#minReplicas
        '''
        result = self._values.get("min_replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HorizontalPodAutoscalerSpecV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HorizontalPodAutoscalerSpecV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "max_replicas": "maxReplicas",
        "scale_target_ref": "scaleTargetRef",
        "metrics": "metrics",
        "min_replicas": "minReplicas",
    },
)
class HorizontalPodAutoscalerSpecV2Beta1:
    def __init__(
        self,
        *,
        max_replicas: jsii.Number,
        scale_target_ref: typing.Union[CrossVersionObjectReferenceV2Beta1, typing.Dict[str, typing.Any]],
        metrics: typing.Optional[typing.Sequence[typing.Union["MetricSpecV2Beta1", typing.Dict[str, typing.Any]]]] = None,
        min_replicas: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler.

        :param max_replicas: maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas.
        :param scale_target_ref: 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.
        :param metrics: 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.
        :param min_replicas: 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.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec
        '''
        if isinstance(scale_target_ref, dict):
            scale_target_ref = CrossVersionObjectReferenceV2Beta1(**scale_target_ref)
        if __debug__:
            def stub(
                *,
                max_replicas: jsii.Number,
                scale_target_ref: typing.Union[CrossVersionObjectReferenceV2Beta1, typing.Dict[str, typing.Any]],
                metrics: typing.Optional[typing.Sequence[typing.Union[MetricSpecV2Beta1, typing.Dict[str, typing.Any]]]] = None,
                min_replicas: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_replicas", value=max_replicas, expected_type=type_hints["max_replicas"])
            check_type(argname="argument scale_target_ref", value=scale_target_ref, expected_type=type_hints["scale_target_ref"])
            check_type(argname="argument metrics", value=metrics, expected_type=type_hints["metrics"])
            check_type(argname="argument min_replicas", value=min_replicas, expected_type=type_hints["min_replicas"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_replicas": max_replicas,
            "scale_target_ref": scale_target_ref,
        }
        if metrics is not None:
            self._values["metrics"] = metrics
        if min_replicas is not None:
            self._values["min_replicas"] = min_replicas

    @builtins.property
    def max_replicas(self) -> jsii.Number:
        '''maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.

        It cannot be less that minReplicas.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec#maxReplicas
        '''
        result = self._values.get("max_replicas")
        assert result is not None, "Required property 'max_replicas' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def scale_target_ref(self) -> CrossVersionObjectReferenceV2Beta1:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec#scaleTargetRef
        '''
        result = self._values.get("scale_target_ref")
        assert result is not None, "Required property 'scale_target_ref' is missing"
        return typing.cast(CrossVersionObjectReferenceV2Beta1, result)

    @builtins.property
    def metrics(self) -> typing.Optional[typing.List["MetricSpecV2Beta1"]]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec#metrics
        '''
        result = self._values.get("metrics")
        return typing.cast(typing.Optional[typing.List["MetricSpecV2Beta1"]], result)

    @builtins.property
    def min_replicas(self) -> typing.Optional[jsii.Number]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec#minReplicas
        '''
        result = self._values.get("min_replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HorizontalPodAutoscalerSpecV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HorizontalPodAutoscalerSpecV2Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "max_replicas": "maxReplicas",
        "scale_target_ref": "scaleTargetRef",
        "behavior": "behavior",
        "metrics": "metrics",
        "min_replicas": "minReplicas",
    },
)
class HorizontalPodAutoscalerSpecV2Beta2:
    def __init__(
        self,
        *,
        max_replicas: jsii.Number,
        scale_target_ref: typing.Union[CrossVersionObjectReferenceV2Beta2, typing.Dict[str, typing.Any]],
        behavior: typing.Optional[typing.Union[HorizontalPodAutoscalerBehaviorV2Beta2, typing.Dict[str, typing.Any]]] = None,
        metrics: typing.Optional[typing.Sequence[typing.Union["MetricSpecV2Beta2", typing.Dict[str, typing.Any]]]] = None,
        min_replicas: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler.

        :param max_replicas: maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas.
        :param scale_target_ref: 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.
        :param behavior: 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.
        :param metrics: 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.
        :param min_replicas: 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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec
        '''
        if isinstance(scale_target_ref, dict):
            scale_target_ref = CrossVersionObjectReferenceV2Beta2(**scale_target_ref)
        if isinstance(behavior, dict):
            behavior = HorizontalPodAutoscalerBehaviorV2Beta2(**behavior)
        if __debug__:
            def stub(
                *,
                max_replicas: jsii.Number,
                scale_target_ref: typing.Union[CrossVersionObjectReferenceV2Beta2, typing.Dict[str, typing.Any]],
                behavior: typing.Optional[typing.Union[HorizontalPodAutoscalerBehaviorV2Beta2, typing.Dict[str, typing.Any]]] = None,
                metrics: typing.Optional[typing.Sequence[typing.Union[MetricSpecV2Beta2, typing.Dict[str, typing.Any]]]] = None,
                min_replicas: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_replicas", value=max_replicas, expected_type=type_hints["max_replicas"])
            check_type(argname="argument scale_target_ref", value=scale_target_ref, expected_type=type_hints["scale_target_ref"])
            check_type(argname="argument behavior", value=behavior, expected_type=type_hints["behavior"])
            check_type(argname="argument metrics", value=metrics, expected_type=type_hints["metrics"])
            check_type(argname="argument min_replicas", value=min_replicas, expected_type=type_hints["min_replicas"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_replicas": max_replicas,
            "scale_target_ref": scale_target_ref,
        }
        if behavior is not None:
            self._values["behavior"] = behavior
        if metrics is not None:
            self._values["metrics"] = metrics
        if min_replicas is not None:
            self._values["min_replicas"] = min_replicas

    @builtins.property
    def max_replicas(self) -> jsii.Number:
        '''maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.

        It cannot be less that minReplicas.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec#maxReplicas
        '''
        result = self._values.get("max_replicas")
        assert result is not None, "Required property 'max_replicas' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def scale_target_ref(self) -> CrossVersionObjectReferenceV2Beta2:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec#scaleTargetRef
        '''
        result = self._values.get("scale_target_ref")
        assert result is not None, "Required property 'scale_target_ref' is missing"
        return typing.cast(CrossVersionObjectReferenceV2Beta2, result)

    @builtins.property
    def behavior(self) -> typing.Optional[HorizontalPodAutoscalerBehaviorV2Beta2]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec#behavior
        '''
        result = self._values.get("behavior")
        return typing.cast(typing.Optional[HorizontalPodAutoscalerBehaviorV2Beta2], result)

    @builtins.property
    def metrics(self) -> typing.Optional[typing.List["MetricSpecV2Beta2"]]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec#metrics
        '''
        result = self._values.get("metrics")
        return typing.cast(typing.Optional[typing.List["MetricSpecV2Beta2"]], result)

    @builtins.property
    def min_replicas(self) -> typing.Optional[jsii.Number]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec#minReplicas
        '''
        result = self._values.get("min_replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HorizontalPodAutoscalerSpecV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HostAlias",
    jsii_struct_bases=[],
    name_mapping={"hostnames": "hostnames", "ip": "ip"},
)
class HostAlias:
    def __init__(
        self,
        *,
        hostnames: typing.Optional[typing.Sequence[builtins.str]] = None,
        ip: typing.Optional[builtins.str] = None,
    ) -> None:
        '''HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file.

        :param hostnames: Hostnames for the above IP address.
        :param ip: IP address of the host file entry.

        :schema: io.k8s.api.core.v1.HostAlias
        '''
        if __debug__:
            def stub(
                *,
                hostnames: typing.Optional[typing.Sequence[builtins.str]] = None,
                ip: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument hostnames", value=hostnames, expected_type=type_hints["hostnames"])
            check_type(argname="argument ip", value=ip, expected_type=type_hints["ip"])
        self._values: typing.Dict[str, typing.Any] = {}
        if hostnames is not None:
            self._values["hostnames"] = hostnames
        if ip is not None:
            self._values["ip"] = ip

    @builtins.property
    def hostnames(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Hostnames for the above IP address.

        :schema: io.k8s.api.core.v1.HostAlias#hostnames
        '''
        result = self._values.get("hostnames")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def ip(self) -> typing.Optional[builtins.str]:
        '''IP address of the host file entry.

        :schema: io.k8s.api.core.v1.HostAlias#ip
        '''
        result = self._values.get("ip")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HostAlias(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HostPathVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"path": "path", "type": "type"},
)
class HostPathVolumeSource:
    def __init__(
        self,
        *,
        path: builtins.str,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a host path mapped into a pod.

        Host path volumes do not support ownership management or SELinux relabeling.

        :param path: Path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
        :param type: Type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath. Default: More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

        :schema: io.k8s.api.core.v1.HostPathVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                path: builtins.str,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {
            "path": path,
        }
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def path(self) -> builtins.str:
        '''Path of the directory on the host.

        If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

        :schema: io.k8s.api.core.v1.HostPathVolumeSource#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''Type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath.

        :default: More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

        :schema: io.k8s.api.core.v1.HostPathVolumeSource#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HostPathVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HostPortRangeV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"max": "max", "min": "min"},
)
class HostPortRangeV1Beta1:
    def __init__(self, *, max: jsii.Number, min: jsii.Number) -> None:
        '''HostPortRange defines a range of host ports that will be enabled by a policy for pods to use.

        It requires both the start and end to be defined.

        :param max: max is the end of the range, inclusive.
        :param min: min is the start of the range, inclusive.

        :schema: io.k8s.api.policy.v1beta1.HostPortRange
        '''
        if __debug__:
            def stub(*, max: jsii.Number, min: jsii.Number) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max", value=max, expected_type=type_hints["max"])
            check_type(argname="argument min", value=min, expected_type=type_hints["min"])
        self._values: typing.Dict[str, typing.Any] = {
            "max": max,
            "min": min,
        }

    @builtins.property
    def max(self) -> jsii.Number:
        '''max is the end of the range, inclusive.

        :schema: io.k8s.api.policy.v1beta1.HostPortRange#max
        '''
        result = self._values.get("max")
        assert result is not None, "Required property 'max' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def min(self) -> jsii.Number:
        '''min is the start of the range, inclusive.

        :schema: io.k8s.api.policy.v1beta1.HostPortRange#min
        '''
        result = self._values.get("min")
        assert result is not None, "Required property 'min' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HostPortRangeV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HpaScalingPolicyV2",
    jsii_struct_bases=[],
    name_mapping={"period_seconds": "periodSeconds", "type": "type", "value": "value"},
)
class HpaScalingPolicyV2:
    def __init__(
        self,
        *,
        period_seconds: jsii.Number,
        type: builtins.str,
        value: jsii.Number,
    ) -> None:
        '''HPAScalingPolicy is a single policy which must hold true for a specified past interval.

        :param period_seconds: 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).
        :param type: Type is used to specify the scaling policy.
        :param value: Value contains the amount of change which is permitted by the policy. It must be greater than zero

        :schema: io.k8s.api.autoscaling.v2.HPAScalingPolicy
        '''
        if __debug__:
            def stub(
                *,
                period_seconds: jsii.Number,
                type: builtins.str,
                value: jsii.Number,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument period_seconds", value=period_seconds, expected_type=type_hints["period_seconds"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "period_seconds": period_seconds,
            "type": type,
            "value": value,
        }

    @builtins.property
    def period_seconds(self) -> jsii.Number:
        '''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).

        :schema: io.k8s.api.autoscaling.v2.HPAScalingPolicy#periodSeconds
        '''
        result = self._values.get("period_seconds")
        assert result is not None, "Required property 'period_seconds' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def type(self) -> builtins.str:
        '''Type is used to specify the scaling policy.

        :schema: io.k8s.api.autoscaling.v2.HPAScalingPolicy#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def value(self) -> jsii.Number:
        '''Value contains the amount of change which is permitted by the policy.

        It must be greater than zero

        :schema: io.k8s.api.autoscaling.v2.HPAScalingPolicy#value
        '''
        result = self._values.get("value")
        assert result is not None, "Required property 'value' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HpaScalingPolicyV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HpaScalingPolicyV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"period_seconds": "periodSeconds", "type": "type", "value": "value"},
)
class HpaScalingPolicyV2Beta2:
    def __init__(
        self,
        *,
        period_seconds: jsii.Number,
        type: builtins.str,
        value: jsii.Number,
    ) -> None:
        '''HPAScalingPolicy is a single policy which must hold true for a specified past interval.

        :param period_seconds: 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).
        :param type: Type is used to specify the scaling policy.
        :param value: Value contains the amount of change which is permitted by the policy. It must be greater than zero

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy
        '''
        if __debug__:
            def stub(
                *,
                period_seconds: jsii.Number,
                type: builtins.str,
                value: jsii.Number,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument period_seconds", value=period_seconds, expected_type=type_hints["period_seconds"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "period_seconds": period_seconds,
            "type": type,
            "value": value,
        }

    @builtins.property
    def period_seconds(self) -> jsii.Number:
        '''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).

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy#periodSeconds
        '''
        result = self._values.get("period_seconds")
        assert result is not None, "Required property 'period_seconds' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def type(self) -> builtins.str:
        '''Type is used to specify the scaling policy.

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def value(self) -> jsii.Number:
        '''Value contains the amount of change which is permitted by the policy.

        It must be greater than zero

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy#value
        '''
        result = self._values.get("value")
        assert result is not None, "Required property 'value' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HpaScalingPolicyV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HpaScalingRulesV2",
    jsii_struct_bases=[],
    name_mapping={
        "policies": "policies",
        "select_policy": "selectPolicy",
        "stabilization_window_seconds": "stabilizationWindowSeconds",
    },
)
class HpaScalingRulesV2:
    def __init__(
        self,
        *,
        policies: typing.Optional[typing.Sequence[typing.Union[HpaScalingPolicyV2, typing.Dict[str, typing.Any]]]] = None,
        select_policy: typing.Optional[builtins.str] = None,
        stabilization_window_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''HPAScalingRules configures the scaling behavior for one direction.

        These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.

        :param policies: 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
        :param select_policy: selectPolicy is used to specify which policy should be used. If not set, the default value Max is used.
        :param stabilization_window_seconds: 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).

        :schema: io.k8s.api.autoscaling.v2.HPAScalingRules
        '''
        if __debug__:
            def stub(
                *,
                policies: typing.Optional[typing.Sequence[typing.Union[HpaScalingPolicyV2, typing.Dict[str, typing.Any]]]] = None,
                select_policy: typing.Optional[builtins.str] = None,
                stabilization_window_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument policies", value=policies, expected_type=type_hints["policies"])
            check_type(argname="argument select_policy", value=select_policy, expected_type=type_hints["select_policy"])
            check_type(argname="argument stabilization_window_seconds", value=stabilization_window_seconds, expected_type=type_hints["stabilization_window_seconds"])
        self._values: typing.Dict[str, typing.Any] = {}
        if policies is not None:
            self._values["policies"] = policies
        if select_policy is not None:
            self._values["select_policy"] = select_policy
        if stabilization_window_seconds is not None:
            self._values["stabilization_window_seconds"] = stabilization_window_seconds

    @builtins.property
    def policies(self) -> typing.Optional[typing.List[HpaScalingPolicyV2]]:
        '''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

        :schema: io.k8s.api.autoscaling.v2.HPAScalingRules#policies
        '''
        result = self._values.get("policies")
        return typing.cast(typing.Optional[typing.List[HpaScalingPolicyV2]], result)

    @builtins.property
    def select_policy(self) -> typing.Optional[builtins.str]:
        '''selectPolicy is used to specify which policy should be used.

        If not set, the default value Max is used.

        :schema: io.k8s.api.autoscaling.v2.HPAScalingRules#selectPolicy
        '''
        result = self._values.get("select_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def stabilization_window_seconds(self) -> typing.Optional[jsii.Number]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2.HPAScalingRules#stabilizationWindowSeconds
        '''
        result = self._values.get("stabilization_window_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HpaScalingRulesV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HpaScalingRulesV2Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "policies": "policies",
        "select_policy": "selectPolicy",
        "stabilization_window_seconds": "stabilizationWindowSeconds",
    },
)
class HpaScalingRulesV2Beta2:
    def __init__(
        self,
        *,
        policies: typing.Optional[typing.Sequence[typing.Union[HpaScalingPolicyV2Beta2, typing.Dict[str, typing.Any]]]] = None,
        select_policy: typing.Optional[builtins.str] = None,
        stabilization_window_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''HPAScalingRules configures the scaling behavior for one direction.

        These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.

        :param policies: 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
        :param select_policy: selectPolicy is used to specify which policy should be used. If not set, the default value MaxPolicySelect is used.
        :param stabilization_window_seconds: 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).

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingRules
        '''
        if __debug__:
            def stub(
                *,
                policies: typing.Optional[typing.Sequence[typing.Union[HpaScalingPolicyV2Beta2, typing.Dict[str, typing.Any]]]] = None,
                select_policy: typing.Optional[builtins.str] = None,
                stabilization_window_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument policies", value=policies, expected_type=type_hints["policies"])
            check_type(argname="argument select_policy", value=select_policy, expected_type=type_hints["select_policy"])
            check_type(argname="argument stabilization_window_seconds", value=stabilization_window_seconds, expected_type=type_hints["stabilization_window_seconds"])
        self._values: typing.Dict[str, typing.Any] = {}
        if policies is not None:
            self._values["policies"] = policies
        if select_policy is not None:
            self._values["select_policy"] = select_policy
        if stabilization_window_seconds is not None:
            self._values["stabilization_window_seconds"] = stabilization_window_seconds

    @builtins.property
    def policies(self) -> typing.Optional[typing.List[HpaScalingPolicyV2Beta2]]:
        '''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

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingRules#policies
        '''
        result = self._values.get("policies")
        return typing.cast(typing.Optional[typing.List[HpaScalingPolicyV2Beta2]], result)

    @builtins.property
    def select_policy(self) -> typing.Optional[builtins.str]:
        '''selectPolicy is used to specify which policy should be used.

        If not set, the default value MaxPolicySelect is used.

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingRules#selectPolicy
        '''
        result = self._values.get("select_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def stabilization_window_seconds(self) -> typing.Optional[jsii.Number]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2beta2.HPAScalingRules#stabilizationWindowSeconds
        '''
        result = self._values.get("stabilization_window_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HpaScalingRulesV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HttpGetAction",
    jsii_struct_bases=[],
    name_mapping={
        "port": "port",
        "host": "host",
        "http_headers": "httpHeaders",
        "path": "path",
        "scheme": "scheme",
    },
)
class HttpGetAction:
    def __init__(
        self,
        *,
        port: "IntOrString",
        host: typing.Optional[builtins.str] = None,
        http_headers: typing.Optional[typing.Sequence[typing.Union["HttpHeader", typing.Dict[str, typing.Any]]]] = None,
        path: typing.Optional[builtins.str] = None,
        scheme: typing.Optional["IoK8SApiCoreV1HttpGetActionScheme"] = None,
    ) -> None:
        '''HTTPGetAction describes an action based on HTTP Get requests.

        :param port: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.
        :param host: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead.
        :param http_headers: Custom headers to set in the request. HTTP allows repeated headers.
        :param path: Path to access on the HTTP server.
        :param scheme: Scheme to use for connecting to the host. Defaults to HTTP. Possible enum values: - ``"HTTP"`` means that the scheme used will be http:// - ``"HTTPS"`` means that the scheme used will be https:// Default: HTTP.

        :schema: io.k8s.api.core.v1.HTTPGetAction
        '''
        if __debug__:
            def stub(
                *,
                port: IntOrString,
                host: typing.Optional[builtins.str] = None,
                http_headers: typing.Optional[typing.Sequence[typing.Union[HttpHeader, typing.Dict[str, typing.Any]]]] = None,
                path: typing.Optional[builtins.str] = None,
                scheme: typing.Optional[IoK8SApiCoreV1HttpGetActionScheme] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument host", value=host, expected_type=type_hints["host"])
            check_type(argname="argument http_headers", value=http_headers, expected_type=type_hints["http_headers"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument scheme", value=scheme, expected_type=type_hints["scheme"])
        self._values: typing.Dict[str, typing.Any] = {
            "port": port,
        }
        if host is not None:
            self._values["host"] = host
        if http_headers is not None:
            self._values["http_headers"] = http_headers
        if path is not None:
            self._values["path"] = path
        if scheme is not None:
            self._values["scheme"] = scheme

    @builtins.property
    def port(self) -> "IntOrString":
        '''Name or number of the port to access on the container.

        Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.

        :schema: io.k8s.api.core.v1.HTTPGetAction#port
        '''
        result = self._values.get("port")
        assert result is not None, "Required property 'port' is missing"
        return typing.cast("IntOrString", result)

    @builtins.property
    def host(self) -> typing.Optional[builtins.str]:
        '''Host name to connect to, defaults to the pod IP.

        You probably want to set "Host" in httpHeaders instead.

        :schema: io.k8s.api.core.v1.HTTPGetAction#host
        '''
        result = self._values.get("host")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def http_headers(self) -> typing.Optional[typing.List["HttpHeader"]]:
        '''Custom headers to set in the request.

        HTTP allows repeated headers.

        :schema: io.k8s.api.core.v1.HTTPGetAction#httpHeaders
        '''
        result = self._values.get("http_headers")
        return typing.cast(typing.Optional[typing.List["HttpHeader"]], result)

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''Path to access on the HTTP server.

        :schema: io.k8s.api.core.v1.HTTPGetAction#path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def scheme(self) -> typing.Optional["IoK8SApiCoreV1HttpGetActionScheme"]:
        '''Scheme to use for connecting to the host. Defaults to HTTP.

        Possible enum values:

        - ``"HTTP"`` means that the scheme used will be http://
        - ``"HTTPS"`` means that the scheme used will be https://

        :default: HTTP.

        :schema: io.k8s.api.core.v1.HTTPGetAction#scheme
        '''
        result = self._values.get("scheme")
        return typing.cast(typing.Optional["IoK8SApiCoreV1HttpGetActionScheme"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpGetAction(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HttpHeader",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "value": "value"},
)
class HttpHeader:
    def __init__(self, *, name: builtins.str, value: builtins.str) -> None:
        '''HTTPHeader describes a custom header to be used in HTTP probes.

        :param name: The header field name.
        :param value: The header field value.

        :schema: io.k8s.api.core.v1.HTTPHeader
        '''
        if __debug__:
            def stub(*, name: builtins.str, value: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "value": value,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''The header field name.

        :schema: io.k8s.api.core.v1.HTTPHeader#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def value(self) -> builtins.str:
        '''The header field value.

        :schema: io.k8s.api.core.v1.HTTPHeader#value
        '''
        result = self._values.get("value")
        assert result is not None, "Required property 'value' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpHeader(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HttpIngressPath",
    jsii_struct_bases=[],
    name_mapping={"backend": "backend", "path_type": "pathType", "path": "path"},
)
class HttpIngressPath:
    def __init__(
        self,
        *,
        backend: typing.Union["IngressBackend", typing.Dict[str, typing.Any]],
        path_type: builtins.str,
        path: typing.Optional[builtins.str] = None,
    ) -> None:
        '''HTTPIngressPath associates a path with a backend.

        Incoming urls matching the path are forwarded to the backend.

        :param backend: Backend defines the referenced service endpoint to which the traffic will be forwarded to.
        :param path_type: PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is done on a path element by element basis. A path element refers is the list of labels in the path split by the '/' separator. A request is a match for path p if every p is an element-wise prefix of p of the request path. Note that if the last element of the path is a substring of the last element in request path, it is not a match (e.g. /foo/bar matches /foo/bar/baz, but does not match /foo/barbaz). - ImplementationSpecific: Interpretation of the Path matching is up to the IngressClass. Implementations can treat this as a separate PathType or treat it identically to Prefix or Exact path types. Implementations are required to support all path types.
        :param path: Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value "Exact" or "Prefix".

        :schema: io.k8s.api.networking.v1.HTTPIngressPath
        '''
        if isinstance(backend, dict):
            backend = IngressBackend(**backend)
        if __debug__:
            def stub(
                *,
                backend: typing.Union[IngressBackend, typing.Dict[str, typing.Any]],
                path_type: builtins.str,
                path: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument backend", value=backend, expected_type=type_hints["backend"])
            check_type(argname="argument path_type", value=path_type, expected_type=type_hints["path_type"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
        self._values: typing.Dict[str, typing.Any] = {
            "backend": backend,
            "path_type": path_type,
        }
        if path is not None:
            self._values["path"] = path

    @builtins.property
    def backend(self) -> "IngressBackend":
        '''Backend defines the referenced service endpoint to which the traffic will be forwarded to.

        :schema: io.k8s.api.networking.v1.HTTPIngressPath#backend
        '''
        result = self._values.get("backend")
        assert result is not None, "Required property 'backend' is missing"
        return typing.cast("IngressBackend", result)

    @builtins.property
    def path_type(self) -> builtins.str:
        '''PathType determines the interpretation of the Path matching.

        PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is
        done on a path element by element basis. A path element refers is the
        list of labels in the path split by the '/' separator. A request is a
        match for path p if every p is an element-wise prefix of p of the
        request path. Note that if the last element of the path is a substring
        of the last element in request path, it is not a match (e.g. /foo/bar
        matches /foo/bar/baz, but does not match /foo/barbaz).

        - ImplementationSpecific: Interpretation of the Path matching is up to
          the IngressClass. Implementations can treat this as a separate PathType
          or treat it identically to Prefix or Exact path types.
          Implementations are required to support all path types.

        :schema: io.k8s.api.networking.v1.HTTPIngressPath#pathType
        '''
        result = self._values.get("path_type")
        assert result is not None, "Required property 'path_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''Path is matched against the path of an incoming request.

        Currently it can contain characters disallowed from the conventional "path" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value "Exact" or "Prefix".

        :schema: io.k8s.api.networking.v1.HTTPIngressPath#path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpIngressPath(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.HttpIngressRuleValue",
    jsii_struct_bases=[],
    name_mapping={"paths": "paths"},
)
class HttpIngressRuleValue:
    def __init__(
        self,
        *,
        paths: typing.Sequence[typing.Union[HttpIngressPath, typing.Dict[str, typing.Any]]],
    ) -> None:
        '''HTTPIngressRuleValue is a list of http selectors pointing to backends.

        In the example: http:///? -> backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.

        :param paths: A collection of paths that map requests to backends.

        :schema: io.k8s.api.networking.v1.HTTPIngressRuleValue
        '''
        if __debug__:
            def stub(
                *,
                paths: typing.Sequence[typing.Union[HttpIngressPath, typing.Dict[str, typing.Any]]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument paths", value=paths, expected_type=type_hints["paths"])
        self._values: typing.Dict[str, typing.Any] = {
            "paths": paths,
        }

    @builtins.property
    def paths(self) -> typing.List[HttpIngressPath]:
        '''A collection of paths that map requests to backends.

        :schema: io.k8s.api.networking.v1.HTTPIngressRuleValue#paths
        '''
        result = self._values.get("paths")
        assert result is not None, "Required property 'paths' is missing"
        return typing.cast(typing.List[HttpIngressPath], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpIngressRuleValue(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IdRangeV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"max": "max", "min": "min"},
)
class IdRangeV1Beta1:
    def __init__(self, *, max: jsii.Number, min: jsii.Number) -> None:
        '''IDRange provides a min/max of an allowed range of IDs.

        :param max: max is the end of the range, inclusive.
        :param min: min is the start of the range, inclusive.

        :schema: io.k8s.api.policy.v1beta1.IDRange
        '''
        if __debug__:
            def stub(*, max: jsii.Number, min: jsii.Number) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max", value=max, expected_type=type_hints["max"])
            check_type(argname="argument min", value=min, expected_type=type_hints["min"])
        self._values: typing.Dict[str, typing.Any] = {
            "max": max,
            "min": min,
        }

    @builtins.property
    def max(self) -> jsii.Number:
        '''max is the end of the range, inclusive.

        :schema: io.k8s.api.policy.v1beta1.IDRange#max
        '''
        result = self._values.get("max")
        assert result is not None, "Required property 'max' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def min(self) -> jsii.Number:
        '''min is the start of the range, inclusive.

        :schema: io.k8s.api.policy.v1beta1.IDRange#min
        '''
        result = self._values.get("min")
        assert result is not None, "Required property 'min' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IdRangeV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressBackend",
    jsii_struct_bases=[],
    name_mapping={"resource": "resource", "service": "service"},
)
class IngressBackend:
    def __init__(
        self,
        *,
        resource: typing.Optional[typing.Union["TypedLocalObjectReference", typing.Dict[str, typing.Any]]] = None,
        service: typing.Optional[typing.Union["IngressServiceBackend", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressBackend describes all endpoints for a given service and port.

        :param resource: Resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive setting with "Service".
        :param service: Service references a Service as a Backend. This is a mutually exclusive setting with "Resource".

        :schema: io.k8s.api.networking.v1.IngressBackend
        '''
        if isinstance(resource, dict):
            resource = TypedLocalObjectReference(**resource)
        if isinstance(service, dict):
            service = IngressServiceBackend(**service)
        if __debug__:
            def stub(
                *,
                resource: typing.Optional[typing.Union[TypedLocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                service: typing.Optional[typing.Union[IngressServiceBackend, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument resource", value=resource, expected_type=type_hints["resource"])
            check_type(argname="argument service", value=service, expected_type=type_hints["service"])
        self._values: typing.Dict[str, typing.Any] = {}
        if resource is not None:
            self._values["resource"] = resource
        if service is not None:
            self._values["service"] = service

    @builtins.property
    def resource(self) -> typing.Optional["TypedLocalObjectReference"]:
        '''Resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object.

        If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive setting with "Service".

        :schema: io.k8s.api.networking.v1.IngressBackend#resource
        '''
        result = self._values.get("resource")
        return typing.cast(typing.Optional["TypedLocalObjectReference"], result)

    @builtins.property
    def service(self) -> typing.Optional["IngressServiceBackend"]:
        '''Service references a Service as a Backend.

        This is a mutually exclusive setting with "Resource".

        :schema: io.k8s.api.networking.v1.IngressBackend#service
        '''
        result = self._values.get("service")
        return typing.cast(typing.Optional["IngressServiceBackend"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressBackend(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressClassParametersReference",
    jsii_struct_bases=[],
    name_mapping={
        "kind": "kind",
        "name": "name",
        "api_group": "apiGroup",
        "namespace": "namespace",
        "scope": "scope",
    },
)
class IngressClassParametersReference:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_group: typing.Optional[builtins.str] = None,
        namespace: typing.Optional[builtins.str] = None,
        scope: typing.Optional[builtins.str] = None,
    ) -> None:
        '''IngressClassParametersReference identifies an API object.

        This can be used to specify a cluster or namespace-scoped resource.

        :param kind: Kind is the type of resource being referenced.
        :param name: Name is the name of resource being referenced.
        :param api_group: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.
        :param namespace: Namespace is the namespace of the resource being referenced. This field is required when scope is set to "Namespace" and must be unset when scope is set to "Cluster".
        :param scope: Scope represents if this refers to a cluster or namespace scoped resource. This may be set to "Cluster" (default) or "Namespace".

        :schema: io.k8s.api.networking.v1.IngressClassParametersReference
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_group: typing.Optional[builtins.str] = None,
                namespace: typing.Optional[builtins.str] = None,
                scope: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_group", value=api_group, expected_type=type_hints["api_group"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_group is not None:
            self._values["api_group"] = api_group
        if namespace is not None:
            self._values["namespace"] = namespace
        if scope is not None:
            self._values["scope"] = scope

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind is the type of resource being referenced.

        :schema: io.k8s.api.networking.v1.IngressClassParametersReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the name of resource being referenced.

        :schema: io.k8s.api.networking.v1.IngressClassParametersReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_group(self) -> typing.Optional[builtins.str]:
        '''APIGroup is the group for the resource being referenced.

        If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

        :schema: io.k8s.api.networking.v1.IngressClassParametersReference#apiGroup
        '''
        result = self._values.get("api_group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace is the namespace of the resource being referenced.

        This field is required when scope is set to "Namespace" and must be unset when scope is set to "Cluster".

        :schema: io.k8s.api.networking.v1.IngressClassParametersReference#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def scope(self) -> typing.Optional[builtins.str]:
        '''Scope represents if this refers to a cluster or namespace scoped resource.

        This may be set to "Cluster" (default) or "Namespace".

        :schema: io.k8s.api.networking.v1.IngressClassParametersReference#scope
        '''
        result = self._values.get("scope")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressClassParametersReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressClassSpec",
    jsii_struct_bases=[],
    name_mapping={"controller": "controller", "parameters": "parameters"},
)
class IngressClassSpec:
    def __init__(
        self,
        *,
        controller: typing.Optional[builtins.str] = None,
        parameters: typing.Optional[typing.Union[IngressClassParametersReference, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressClassSpec provides information about the class of an Ingress.

        :param controller: Controller refers to the name of the controller that should handle this class. This allows for different "flavors" that are controlled by the same controller. For example, you may have different Parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. "acme.io/ingress-controller". This field is immutable.
        :param parameters: Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.

        :schema: io.k8s.api.networking.v1.IngressClassSpec
        '''
        if isinstance(parameters, dict):
            parameters = IngressClassParametersReference(**parameters)
        if __debug__:
            def stub(
                *,
                controller: typing.Optional[builtins.str] = None,
                parameters: typing.Optional[typing.Union[IngressClassParametersReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument controller", value=controller, expected_type=type_hints["controller"])
            check_type(argname="argument parameters", value=parameters, expected_type=type_hints["parameters"])
        self._values: typing.Dict[str, typing.Any] = {}
        if controller is not None:
            self._values["controller"] = controller
        if parameters is not None:
            self._values["parameters"] = parameters

    @builtins.property
    def controller(self) -> typing.Optional[builtins.str]:
        '''Controller refers to the name of the controller that should handle this class.

        This allows for different "flavors" that are controlled by the same controller. For example, you may have different Parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. "acme.io/ingress-controller". This field is immutable.

        :schema: io.k8s.api.networking.v1.IngressClassSpec#controller
        '''
        result = self._values.get("controller")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def parameters(self) -> typing.Optional[IngressClassParametersReference]:
        '''Parameters is a link to a custom resource containing additional configuration for the controller.

        This is optional if the controller does not require extra parameters.

        :schema: io.k8s.api.networking.v1.IngressClassSpec#parameters
        '''
        result = self._values.get("parameters")
        return typing.cast(typing.Optional[IngressClassParametersReference], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressClassSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressRule",
    jsii_struct_bases=[],
    name_mapping={"host": "host", "http": "http"},
)
class IngressRule:
    def __init__(
        self,
        *,
        host: typing.Optional[builtins.str] = None,
        http: typing.Optional[typing.Union[HttpIngressRuleValue, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressRule represents the rules mapping the paths under a specified host to the related backend services.

        Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.

        :param host: Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the "host" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the IP in the Spec of the parent Ingress. 2. The ``:`` delimiter is not respected because ports are not allowed. Currently the port of an Ingress is implicitly :80 for http and :443 for https. Both these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue. Host can be "precise" which is a domain name without the terminating dot of a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name prefixed with a single wildcard label (e.g. "*.foo.com"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.
        :param http: 

        :schema: io.k8s.api.networking.v1.IngressRule
        '''
        if isinstance(http, dict):
            http = HttpIngressRuleValue(**http)
        if __debug__:
            def stub(
                *,
                host: typing.Optional[builtins.str] = None,
                http: typing.Optional[typing.Union[HttpIngressRuleValue, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument host", value=host, expected_type=type_hints["host"])
            check_type(argname="argument http", value=http, expected_type=type_hints["http"])
        self._values: typing.Dict[str, typing.Any] = {}
        if host is not None:
            self._values["host"] = host
        if http is not None:
            self._values["http"] = http

    @builtins.property
    def host(self) -> typing.Optional[builtins.str]:
        '''Host is the fully qualified domain name of a network host, as defined by RFC 3986.

        Note the following deviations from the "host" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to
        the IP in the Spec of the parent Ingress.
        2. The ``:`` delimiter is not respected because ports are not allowed.
        Currently the port of an Ingress is implicitly :80 for http and
        :443 for https.
        Both these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.

        Host can be "precise" which is a domain name without the terminating dot of a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name prefixed with a single wildcard label (e.g. "*.foo.com"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.

        :schema: io.k8s.api.networking.v1.IngressRule#host
        '''
        result = self._values.get("host")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def http(self) -> typing.Optional[HttpIngressRuleValue]:
        '''
        :schema: io.k8s.api.networking.v1.IngressRule#http
        '''
        result = self._values.get("http")
        return typing.cast(typing.Optional[HttpIngressRuleValue], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressServiceBackend",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "port": "port"},
)
class IngressServiceBackend:
    def __init__(
        self,
        *,
        name: builtins.str,
        port: typing.Optional[typing.Union["ServiceBackendPort", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressServiceBackend references a Kubernetes Service as a Backend.

        :param name: Name is the referenced service. The service must exist in the same namespace as the Ingress object.
        :param port: Port of the referenced service. A port name or port number is required for a IngressServiceBackend.

        :schema: io.k8s.api.networking.v1.IngressServiceBackend
        '''
        if isinstance(port, dict):
            port = ServiceBackendPort(**port)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                port: typing.Optional[typing.Union[ServiceBackendPort, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if port is not None:
            self._values["port"] = port

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the referenced service.

        The service must exist in the same namespace as the Ingress object.

        :schema: io.k8s.api.networking.v1.IngressServiceBackend#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def port(self) -> typing.Optional["ServiceBackendPort"]:
        '''Port of the referenced service.

        A port name or port number is required for a IngressServiceBackend.

        :schema: io.k8s.api.networking.v1.IngressServiceBackend#port
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional["ServiceBackendPort"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressServiceBackend(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressSpec",
    jsii_struct_bases=[],
    name_mapping={
        "default_backend": "defaultBackend",
        "ingress_class_name": "ingressClassName",
        "rules": "rules",
        "tls": "tls",
    },
)
class IngressSpec:
    def __init__(
        self,
        *,
        default_backend: typing.Optional[typing.Union[IngressBackend, typing.Dict[str, typing.Any]]] = None,
        ingress_class_name: typing.Optional[builtins.str] = None,
        rules: typing.Optional[typing.Sequence[typing.Union[IngressRule, typing.Dict[str, typing.Any]]]] = None,
        tls: typing.Optional[typing.Sequence[typing.Union["IngressTls", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''IngressSpec describes the Ingress the user wishes to exist.

        :param default_backend: DefaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests that do not match any of the rules will be up to the Ingress controller.
        :param ingress_class_name: IngressClassName is the name of the IngressClass cluster resource. The associated IngressClass defines which controller will implement the resource. This replaces the deprecated ``kubernetes.io/ingress.class`` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.
        :param rules: A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.
        :param tls: TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.

        :schema: io.k8s.api.networking.v1.IngressSpec
        '''
        if isinstance(default_backend, dict):
            default_backend = IngressBackend(**default_backend)
        if __debug__:
            def stub(
                *,
                default_backend: typing.Optional[typing.Union[IngressBackend, typing.Dict[str, typing.Any]]] = None,
                ingress_class_name: typing.Optional[builtins.str] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[IngressRule, typing.Dict[str, typing.Any]]]] = None,
                tls: typing.Optional[typing.Sequence[typing.Union[IngressTls, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument default_backend", value=default_backend, expected_type=type_hints["default_backend"])
            check_type(argname="argument ingress_class_name", value=ingress_class_name, expected_type=type_hints["ingress_class_name"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if default_backend is not None:
            self._values["default_backend"] = default_backend
        if ingress_class_name is not None:
            self._values["ingress_class_name"] = ingress_class_name
        if rules is not None:
            self._values["rules"] = rules
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def default_backend(self) -> typing.Optional[IngressBackend]:
        '''DefaultBackend is the backend that should handle requests that don't match any rule.

        If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests that do not match any of the rules will be up to the Ingress controller.

        :schema: io.k8s.api.networking.v1.IngressSpec#defaultBackend
        '''
        result = self._values.get("default_backend")
        return typing.cast(typing.Optional[IngressBackend], result)

    @builtins.property
    def ingress_class_name(self) -> typing.Optional[builtins.str]:
        '''IngressClassName is the name of the IngressClass cluster resource.

        The associated IngressClass defines which controller will implement the resource. This replaces the deprecated ``kubernetes.io/ingress.class`` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.

        :schema: io.k8s.api.networking.v1.IngressSpec#ingressClassName
        '''
        result = self._values.get("ingress_class_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List[IngressRule]]:
        '''A list of host rules used to configure the Ingress.

        If unspecified, or no rule matches, all traffic is sent to the default backend.

        :schema: io.k8s.api.networking.v1.IngressSpec#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List[IngressRule]], result)

    @builtins.property
    def tls(self) -> typing.Optional[typing.List["IngressTls"]]:
        '''TLS configuration.

        Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.

        :schema: io.k8s.api.networking.v1.IngressSpec#tls
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional[typing.List["IngressTls"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IngressTls",
    jsii_struct_bases=[],
    name_mapping={"hosts": "hosts", "secret_name": "secretName"},
)
class IngressTls:
    def __init__(
        self,
        *,
        hosts: typing.Optional[typing.Sequence[builtins.str]] = None,
        secret_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''IngressTLS describes the transport layer security associated with an Ingress.

        :param hosts: Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. Default: the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.
        :param secret_name: SecretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.

        :schema: io.k8s.api.networking.v1.IngressTLS
        '''
        if __debug__:
            def stub(
                *,
                hosts: typing.Optional[typing.Sequence[builtins.str]] = None,
                secret_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument hosts", value=hosts, expected_type=type_hints["hosts"])
            check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if hosts is not None:
            self._values["hosts"] = hosts
        if secret_name is not None:
            self._values["secret_name"] = secret_name

    @builtins.property
    def hosts(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Hosts are a list of hosts included in the TLS certificate.

        The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.

        :default: the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.

        :schema: io.k8s.api.networking.v1.IngressTLS#hosts
        '''
        result = self._values.get("hosts")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def secret_name(self) -> typing.Optional[builtins.str]:
        '''SecretName is the name of the secret used to terminate TLS traffic on port 443.

        Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.

        :schema: io.k8s.api.networking.v1.IngressTLS#secretName
        '''
        result = self._values.get("secret_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IngressTls(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class IntOrString(metaclass=jsii.JSIIMeta, jsii_type="cdk8s-plus-23.k8s.IntOrString"):
    '''
    :schema: io.k8s.apimachinery.pkg.util.intstr.IntOrString
    '''

    @jsii.member(jsii_name="fromNumber")
    @builtins.classmethod
    def from_number(cls, value: jsii.Number) -> "IntOrString":
        '''
        :param value: -
        '''
        if __debug__:
            def stub(value: jsii.Number) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        return typing.cast("IntOrString", jsii.sinvoke(cls, "fromNumber", [value]))

    @jsii.member(jsii_name="fromString")
    @builtins.classmethod
    def from_string(cls, value: builtins.str) -> "IntOrString":
        '''
        :param value: -
        '''
        if __debug__:
            def stub(value: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        return typing.cast("IntOrString", jsii.sinvoke(cls, "fromString", [value]))

    @builtins.property
    @jsii.member(jsii_name="value")
    def value(self) -> typing.Any:
        return typing.cast(typing.Any, jsii.get(self, "value"))


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiAppsV1DaemonSetUpdateStrategyType")
class IoK8SApiAppsV1DaemonSetUpdateStrategyType(enum.Enum):
    '''Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.

    Possible enum values:

    - ``"OnDelete"`` Replace the old daemons only when it's killed
    - ``"RollingUpdate"`` Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.

    :default: RollingUpdate.

    :schema: IoK8SApiAppsV1DaemonSetUpdateStrategyType
    '''

    ON_DELETE = "ON_DELETE"
    '''OnDelete.'''
    ROLLING_UPDATE = "ROLLING_UPDATE"
    '''RollingUpdate.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiAppsV1DeploymentStrategyType")
class IoK8SApiAppsV1DeploymentStrategyType(enum.Enum):
    '''Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.

    Possible enum values:

    - ``"Recreate"`` Kill all existing pods before creating new ones.
    - ``"RollingUpdate"`` Replace the old ReplicaSets by new one using rolling update i.e gradually scale down the old ReplicaSets and scale up the new one.

    :default: RollingUpdate.

    :schema: IoK8SApiAppsV1DeploymentStrategyType
    '''

    RECREATE = "RECREATE"
    '''Recreate.'''
    ROLLING_UPDATE = "ROLLING_UPDATE"
    '''RollingUpdate.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy"
)
class IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy(enum.Enum):
    '''podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down.

    The default policy is ``OrderedReady``, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is ``Parallel`` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.

    Possible enum values:

    - ``"OrderedReady"`` will create pods in strictly increasing order on scale up and strictly decreasing order on scale down, progressing only when the previous pod is ready or terminated. At most one pod will be changed at any time.
    - ``"Parallel"`` will create and delete pods as soon as the stateful set replica count is changed, and will not wait for pods to be ready or complete termination.

    :schema: IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy
    '''

    ORDERED_READY = "ORDERED_READY"
    '''OrderedReady.'''
    PARALLEL = "PARALLEL"
    '''Parallel.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiAppsV1StatefulSetUpdateStrategyType")
class IoK8SApiAppsV1StatefulSetUpdateStrategyType(enum.Enum):
    '''Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate.

    Possible enum values:

    - ``"OnDelete"`` triggers the legacy behavior. Version tracking and ordered rolling restarts are disabled. Pods are recreated from the StatefulSetSpec when they are manually deleted. When a scale operation is performed with this strategy,specification version indicated by the StatefulSet's currentRevision.
    - ``"RollingUpdate"`` indicates that update will be applied to all Pods in the StatefulSet with respect to the StatefulSet ordering constraints. When a scale operation is performed with this strategy, new Pods will be created from the specification version indicated by the StatefulSet's updateRevision.

    :default: RollingUpdate.

    :schema: IoK8SApiAppsV1StatefulSetUpdateStrategyType
    '''

    ON_DELETE = "ON_DELETE"
    '''OnDelete.'''
    ROLLING_UPDATE = "ROLLING_UPDATE"
    '''RollingUpdate.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiBatchV1CronJobSpecConcurrencyPolicy")
class IoK8SApiBatchV1CronJobSpecConcurrencyPolicy(enum.Enum):
    '''Specifies how to treat concurrent executions of a Job.

    Valid values are: - "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - "Replace": cancels currently running job and replaces it with a new one

    Possible enum values:

    - ``"Allow"`` allows CronJobs to run concurrently.
    - ``"Forbid"`` forbids concurrent runs, skipping next run if previous hasn't finished yet.
    - ``"Replace"`` cancels currently running job and replaces it with a new one.

    :schema: IoK8SApiBatchV1CronJobSpecConcurrencyPolicy
    '''

    ALLOW = "ALLOW"
    '''Allow.'''
    FORBID = "FORBID"
    '''Forbid.'''
    REPLACE = "REPLACE"
    '''Replace.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ContainerImagePullPolicy")
class IoK8SApiCoreV1ContainerImagePullPolicy(enum.Enum):
    '''Image pull policy.

    One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

    Possible enum values:

    - ``"Always"`` means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
    - ``"IfNotPresent"`` means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails.
    - ``"Never"`` means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present

    :default: Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

    :schema: IoK8SApiCoreV1ContainerImagePullPolicy
    '''

    ALWAYS = "ALWAYS"
    '''Always.'''
    IF_NOT_PRESENT = "IF_NOT_PRESENT"
    '''IfNotPresent.'''
    NEVER = "NEVER"
    '''Never.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ContainerPortProtocol")
class IoK8SApiCoreV1ContainerPortProtocol(enum.Enum):
    '''Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".

    Possible enum values:

    - ``"SCTP"`` is the SCTP protocol.
    - ``"TCP"`` is the TCP protocol.
    - ``"UDP"`` is the UDP protocol.

    :default: TCP".

    :schema: IoK8SApiCoreV1ContainerPortProtocol
    '''

    SCTP = "SCTP"
    '''SCTP.'''
    TCP = "TCP"
    '''TCP.'''
    UDP = "UDP"
    '''UDP.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ContainerTerminationMessagePolicy"
)
class IoK8SApiCoreV1ContainerTerminationMessagePolicy(enum.Enum):
    '''Indicate how the termination message should be populated.

    File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

    Possible enum values:

    - ``"FallbackToLogsOnError"`` will read the most recent contents of the container logs for the container status message when the container exits with an error and the terminationMessagePath has no contents.
    - ``"File"`` is the default behavior and will set the container status message to the contents of the container's terminationMessagePath when the container exits.

    :default: File. Cannot be updated.

    :schema: IoK8SApiCoreV1ContainerTerminationMessagePolicy
    '''

    FALLBACK_TO_LOGS_ON_ERROR = "FALLBACK_TO_LOGS_ON_ERROR"
    '''FallbackToLogsOnError.'''
    FILE = "FILE"
    '''File.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1EndpointPortProtocol")
class IoK8SApiCoreV1EndpointPortProtocol(enum.Enum):
    '''The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.

    Possible enum values:

    - ``"SCTP"`` is the SCTP protocol.
    - ``"TCP"`` is the TCP protocol.
    - ``"UDP"`` is the UDP protocol.

    :default: TCP.

    :schema: IoK8SApiCoreV1EndpointPortProtocol
    '''

    SCTP = "SCTP"
    '''SCTP.'''
    TCP = "TCP"
    '''TCP.'''
    UDP = "UDP"
    '''UDP.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1EphemeralContainerImagePullPolicy"
)
class IoK8SApiCoreV1EphemeralContainerImagePullPolicy(enum.Enum):
    '''Image pull policy.

    One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

    Possible enum values:

    - ``"Always"`` means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
    - ``"IfNotPresent"`` means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails.
    - ``"Never"`` means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present

    :default: Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images

    :schema: IoK8SApiCoreV1EphemeralContainerImagePullPolicy
    '''

    ALWAYS = "ALWAYS"
    '''Always.'''
    IF_NOT_PRESENT = "IF_NOT_PRESENT"
    '''IfNotPresent.'''
    NEVER = "NEVER"
    '''Never.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy"
)
class IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy(enum.Enum):
    '''Indicate how the termination message should be populated.

    File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

    Possible enum values:

    - ``"FallbackToLogsOnError"`` will read the most recent contents of the container logs for the container status message when the container exits with an error and the terminationMessagePath has no contents.
    - ``"File"`` is the default behavior and will set the container status message to the contents of the container's terminationMessagePath when the container exits.

    :default: File. Cannot be updated.

    :schema: IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy
    '''

    FALLBACK_TO_LOGS_ON_ERROR = "FALLBACK_TO_LOGS_ON_ERROR"
    '''FallbackToLogsOnError.'''
    FILE = "FILE"
    '''File.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1HttpGetActionScheme")
class IoK8SApiCoreV1HttpGetActionScheme(enum.Enum):
    '''Scheme to use for connecting to the host. Defaults to HTTP.

    Possible enum values:

    - ``"HTTP"`` means that the scheme used will be http://
    - ``"HTTPS"`` means that the scheme used will be https://

    :default: HTTP.

    :schema: IoK8SApiCoreV1HttpGetActionScheme
    '''

    HTTP = "HTTP"
    '''HTTP.'''
    HTTPS = "HTTPS"
    '''HTTPS.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1LimitRangeItemType")
class IoK8SApiCoreV1LimitRangeItemType(enum.Enum):
    '''Type of resource that this limit applies to.

    Possible enum values:

    - ``"Container"`` Limit that applies to all containers in a namespace
    - ``"PersistentVolumeClaim"`` Limit that applies to all persistent volume claims in a namespace
    - ``"Pod"`` Limit that applies to all pods in a namespace

    :schema: IoK8SApiCoreV1LimitRangeItemType
    '''

    CONTAINER = "CONTAINER"
    '''Container.'''
    PERSISTENT_VOLUME_CLAIM = "PERSISTENT_VOLUME_CLAIM"
    '''PersistentVolumeClaim.'''
    POD = "POD"
    '''Pod.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1NodeSelectorRequirementOperator")
class IoK8SApiCoreV1NodeSelectorRequirementOperator(enum.Enum):
    '''Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

    Possible enum values:

    - ``"DoesNotExist"``
    - ``"Exists"``
    - ``"Gt"``
    - ``"In"``
    - ``"Lt"``
    - ``"NotIn"``

    :schema: IoK8SApiCoreV1NodeSelectorRequirementOperator
    '''

    DOES_NOT_EXIST = "DOES_NOT_EXIST"
    '''DoesNotExist.'''
    EXISTS = "EXISTS"
    '''Exists.'''
    GT = "GT"
    '''Gt.'''
    IN = "IN"
    '''In.'''
    LT = "LT"
    '''Lt.'''
    NOT_IN = "NOT_IN"
    '''NotIn.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy"
)
class IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy(enum.Enum):
    '''What happens to a persistent volume when released from its claim.

    Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming

    Possible enum values:

    - ``"Delete"`` means the volume will be deleted from Kubernetes on release from its claim. The volume plugin must support Deletion.
    - ``"Recycle"`` means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. The volume plugin must support Recycling.
    - ``"Retain"`` means the volume will be left in its current phase (Released) for manual reclamation by the administrator. The default policy is Retain.

    :schema: IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy
    '''

    DELETE = "DELETE"
    '''Delete.'''
    RECYCLE = "RECYCLE"
    '''Recycle.'''
    RETAIN = "RETAIN"
    '''Retain.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1PodReadinessGateConditionType")
class IoK8SApiCoreV1PodReadinessGateConditionType(enum.Enum):
    '''ConditionType refers to a condition in the pod's condition list with matching type.

    Possible enum values:

    - ``"ContainersReady"`` indicates whether all containers in the pod are ready.
    - ``"Initialized"`` means that all init containers in the pod have started successfully.
    - ``"PodScheduled"`` represents status of the scheduling process for this pod.
    - ``"Ready"`` means the pod is able to service requests and should be added to the load balancing pools of all matching services.

    :schema: IoK8SApiCoreV1PodReadinessGateConditionType
    '''

    CONTAINERS_READY = "CONTAINERS_READY"
    '''ContainersReady.'''
    INITIALIZED = "INITIALIZED"
    '''Initialized.'''
    POD_SCHEDULED = "POD_SCHEDULED"
    '''PodScheduled.'''
    READY = "READY"
    '''Ready.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1PodSpecDnsPolicy")
class IoK8SApiCoreV1PodSpecDnsPolicy(enum.Enum):
    '''Set DNS policy for the pod.

    Defaults to "ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.

    Possible enum values:

    - ``"ClusterFirst"`` indicates that the pod should use cluster DNS first unless hostNetwork is true, if it is available, then fall back on the default (as determined by kubelet) DNS settings.
    - ``"ClusterFirstWithHostNet"`` indicates that the pod should use cluster DNS first, if it is available, then fall back on the default (as determined by kubelet) DNS settings.
    - ``"Default"`` indicates that the pod should use the default (as determined by kubelet) DNS settings.
    - ``"None"`` indicates that the pod should use empty DNS settings. DNS parameters such as nameservers and search paths should be defined via DNSConfig.

    :default: ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.

    :schema: IoK8SApiCoreV1PodSpecDnsPolicy
    '''

    CLUSTER_FIRST = "CLUSTER_FIRST"
    '''ClusterFirst.'''
    CLUSTER_FIRST_WITH_HOST_NET = "CLUSTER_FIRST_WITH_HOST_NET"
    '''ClusterFirstWithHostNet.'''
    DEFAULT = "DEFAULT"
    '''Default.'''
    NONE = "NONE"
    '''None.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1PodSpecRestartPolicy")
class IoK8SApiCoreV1PodSpecRestartPolicy(enum.Enum):
    '''Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy.

    Possible enum values:

    - ``"Always"``
    - ``"Never"``
    - ``"OnFailure"``

    :default: Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy

    :schema: IoK8SApiCoreV1PodSpecRestartPolicy
    '''

    ALWAYS = "ALWAYS"
    '''Always.'''
    NEVER = "NEVER"
    '''Never.'''
    ON_FAILURE = "ON_FAILURE"
    '''OnFailure.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator"
)
class IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator(enum.Enum):
    '''Represents a scope's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist.

    Possible enum values:

    - ``"DoesNotExist"``
    - ``"Exists"``
    - ``"In"``
    - ``"NotIn"``

    :schema: IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator
    '''

    DOES_NOT_EXIST = "DOES_NOT_EXIST"
    '''DoesNotExist.'''
    EXISTS = "EXISTS"
    '''Exists.'''
    IN = "IN"
    '''In.'''
    NOT_IN = "NOT_IN"
    '''NotIn.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName"
)
class IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName(enum.Enum):
    '''The name of the scope that the selector applies to.

    Possible enum values:

    - ``"BestEffort"`` Match all pod objects that have best effort quality of service
    - ``"CrossNamespacePodAffinity"`` Match all pod objects that have cross-namespace pod (anti)affinity mentioned. This is a beta feature enabled by the PodAffinityNamespaceSelector feature flag.
    - ``"NotBestEffort"`` Match all pod objects that do not have best effort quality of service
    - ``"NotTerminating"`` Match all pod objects where spec.activeDeadlineSeconds is nil
    - ``"PriorityClass"`` Match all pod objects that have priority class mentioned
    - ``"Terminating"`` Match all pod objects where spec.activeDeadlineSeconds >=0

    :schema: IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName
    '''

    BEST_EFFORT = "BEST_EFFORT"
    '''BestEffort.'''
    CROSS_NAMESPACE_POD_AFFINITY = "CROSS_NAMESPACE_POD_AFFINITY"
    '''CrossNamespacePodAffinity.'''
    NOT_BEST_EFFORT = "NOT_BEST_EFFORT"
    '''NotBestEffort.'''
    NOT_TERMINATING = "NOT_TERMINATING"
    '''NotTerminating.'''
    PRIORITY_CLASS = "PRIORITY_CLASS"
    '''PriorityClass.'''
    TERMINATING = "TERMINATING"
    '''Terminating.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1SeccompProfileType")
class IoK8SApiCoreV1SeccompProfileType(enum.Enum):
    '''type indicates which kind of seccomp profile will be applied. Valid options are:.

    Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.

    Possible enum values:

    - ``"Localhost"`` indicates a profile defined in a file on the node should be used. The file's location relative to /seccomp.
    - ``"RuntimeDefault"`` represents the default container runtime seccomp profile.
    - ``"Unconfined"`` indicates no seccomp profile is applied (A.K.A. unconfined).

    :schema: IoK8SApiCoreV1SeccompProfileType
    '''

    LOCALHOST = "LOCALHOST"
    '''Localhost.'''
    RUNTIME_DEFAULT = "RUNTIME_DEFAULT"
    '''RuntimeDefault.'''
    UNCONFINED = "UNCONFINED"
    '''Unconfined.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ServicePortProtocol")
class IoK8SApiCoreV1ServicePortProtocol(enum.Enum):
    '''The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". Default is TCP.

    Possible enum values:

    - ``"SCTP"`` is the SCTP protocol.
    - ``"TCP"`` is the TCP protocol.
    - ``"UDP"`` is the UDP protocol.

    :default: TCP.

    :schema: IoK8SApiCoreV1ServicePortProtocol
    '''

    SCTP = "SCTP"
    '''SCTP.'''
    TCP = "TCP"
    '''TCP.'''
    UDP = "UDP"
    '''UDP.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy"
)
class IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy(enum.Enum):
    '''externalTrafficPolicy denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints.

    "Local" preserves the client source IP and avoids a second hop for LoadBalancer and Nodeport type services, but risks potentially imbalanced traffic spreading. "Cluster" obscures the client source IP and may cause a second hop to another node, but should have good overall load-spreading.

    Possible enum values:

    - ``"Cluster"`` specifies node-global (legacy) behavior.
    - ``"Local"`` specifies node-local endpoints behavior.

    :schema: IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy
    '''

    CLUSTER = "CLUSTER"
    '''Cluster.'''
    LOCAL = "LOCAL"
    '''Local.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ServiceSpecSessionAffinity")
class IoK8SApiCoreV1ServiceSpecSessionAffinity(enum.Enum):
    '''Supports "ClientIP" and "None".

    Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

    Possible enum values:

    - ``"ClientIP"`` is the Client IP based.
    - ``"None"`` - no session affinity.

    :default: None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

    :schema: IoK8SApiCoreV1ServiceSpecSessionAffinity
    '''

    CLIENT_IP = "CLIENT_IP"
    '''ClientIP.'''
    NONE = "NONE"
    '''None.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1ServiceSpecType")
class IoK8SApiCoreV1ServiceSpecType(enum.Enum):
    '''type determines how the Service is exposed.

    Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object or EndpointSlice objects. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a virtual IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the same endpoints as the clusterIP. "ExternalName" aliases this service to the specified externalName. Several other fields do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

    Possible enum values:

    - ``"ClusterIP"`` means a service will only be accessible inside the cluster, via the cluster IP.
    - ``"ExternalName"`` means a service consists of only a reference to an external name that kubedns or equivalent will return as a CNAME record, with no exposing or proxying of any pods involved.
    - ``"LoadBalancer"`` means a service will be exposed via an external load balancer (if the cloud provider supports it), in addition to 'NodePort' type.
    - ``"NodePort"`` means a service will be exposed on one port of every node, in addition to 'ClusterIP' type.

    :default: ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object or EndpointSlice objects. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a virtual IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the same endpoints as the clusterIP. "ExternalName" aliases this service to the specified externalName. Several other fields do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

    :schema: IoK8SApiCoreV1ServiceSpecType
    '''

    CLUSTER_IP = "CLUSTER_IP"
    '''ClusterIP.'''
    EXTERNAL_NAME = "EXTERNAL_NAME"
    '''ExternalName.'''
    LOAD_BALANCER = "LOAD_BALANCER"
    '''LoadBalancer.'''
    NODE_PORT = "NODE_PORT"
    '''NodePort.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1TaintEffect")
class IoK8SApiCoreV1TaintEffect(enum.Enum):
    '''Required.

    The effect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule and NoExecute.

    Possible enum values:

    - ``"NoExecute"`` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController.
    - ``"NoSchedule"`` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler.
    - ``"PreferNoSchedule"`` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler.

    :schema: IoK8SApiCoreV1TaintEffect
    '''

    NO_EXECUTE = "NO_EXECUTE"
    '''NoExecute.'''
    NO_SCHEDULE = "NO_SCHEDULE"
    '''NoSchedule.'''
    PREFER_NO_SCHEDULE = "PREFER_NO_SCHEDULE"
    '''PreferNoSchedule.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1TolerationEffect")
class IoK8SApiCoreV1TolerationEffect(enum.Enum):
    '''Effect indicates the taint effect to match.

    Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

    Possible enum values:

    - ``"NoExecute"`` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController.
    - ``"NoSchedule"`` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler.
    - ``"PreferNoSchedule"`` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler.

    :schema: IoK8SApiCoreV1TolerationEffect
    '''

    NO_EXECUTE = "NO_EXECUTE"
    '''NoExecute.'''
    NO_SCHEDULE = "NO_SCHEDULE"
    '''NoSchedule.'''
    PREFER_NO_SCHEDULE = "PREFER_NO_SCHEDULE"
    '''PreferNoSchedule.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1TolerationOperator")
class IoK8SApiCoreV1TolerationOperator(enum.Enum):
    '''Operator represents a key's relationship to the value.

    Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

    Possible enum values:

    - ``"Equal"``
    - ``"Exists"``

    :default: Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

    :schema: IoK8SApiCoreV1TolerationOperator
    '''

    EQUAL = "EQUAL"
    '''Equal.'''
    EXISTS = "EXISTS"
    '''Exists.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable"
)
class IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable(enum.Enum):
    '''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 assignment 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.

    Possible enum values:

    - ``"DoNotSchedule"`` instructs the scheduler not to schedule the pod when constraints are not satisfied.
    - ``"ScheduleAnyway"`` instructs the scheduler to schedule the pod even if constraints are not satisfied.

    :schema: IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable
    '''

    DO_NOT_SCHEDULE = "DO_NOT_SCHEDULE"
    '''DoNotSchedule.'''
    SCHEDULE_ANYWAY = "SCHEDULE_ANYWAY"
    '''ScheduleAnyway.'''


@jsii.enum(jsii_type="cdk8s-plus-23.k8s.IoK8SApiDiscoveryV1EndpointSliceAddressType")
class IoK8SApiDiscoveryV1EndpointSliceAddressType(enum.Enum):
    '''addressType specifies the type of address carried by this EndpointSlice.

    All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.

    Possible enum values:

    - ``"FQDN"`` represents a FQDN.
    - ``"IPv4"`` represents an IPv4 Address.
    - ``"IPv6"`` represents an IPv6 Address.

    :schema: IoK8SApiDiscoveryV1EndpointSliceAddressType
    '''

    FQDN = "FQDN"
    '''FQDN.'''
    I_PV4 = "I_PV4"
    '''IPv4.'''
    I_PV6 = "I_PV6"
    '''IPv6.'''


@jsii.enum(
    jsii_type="cdk8s-plus-23.k8s.IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind"
)
class IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind(enum.Enum):
    '''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

    :schema: IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind
    '''

    DELETE_OPTIONS = "DELETE_OPTIONS"
    '''DeleteOptions.'''


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IpBlock",
    jsii_struct_bases=[],
    name_mapping={"cidr": "cidr", "except_": "except"},
)
class IpBlock:
    def __init__(
        self,
        *,
        cidr: builtins.str,
        except_: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''IPBlock describes a particular CIDR (Ex.

        "192.168.1.1/24","2001:db9::/64") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.

        :param cidr: CIDR is a string representing the IP Block Valid examples are "192.168.1.1/24" or "2001:db9::/64".
        :param except_: Except is a slice of CIDRs that should not be included within an IP Block Valid examples are "192.168.1.1/24" or "2001:db9::/64" Except values will be rejected if they are outside the CIDR range.

        :schema: io.k8s.api.networking.v1.IPBlock
        '''
        if __debug__:
            def stub(
                *,
                cidr: builtins.str,
                except_: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument cidr", value=cidr, expected_type=type_hints["cidr"])
            check_type(argname="argument except_", value=except_, expected_type=type_hints["except_"])
        self._values: typing.Dict[str, typing.Any] = {
            "cidr": cidr,
        }
        if except_ is not None:
            self._values["except_"] = except_

    @builtins.property
    def cidr(self) -> builtins.str:
        '''CIDR is a string representing the IP Block Valid examples are "192.168.1.1/24" or "2001:db9::/64".

        :schema: io.k8s.api.networking.v1.IPBlock#cidr
        '''
        result = self._values.get("cidr")
        assert result is not None, "Required property 'cidr' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def except_(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Except is a slice of CIDRs that should not be included within an IP Block Valid examples are "192.168.1.1/24" or "2001:db9::/64" Except values will be rejected if they are outside the CIDR range.

        :schema: io.k8s.api.networking.v1.IPBlock#except
        '''
        result = self._values.get("except_")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IpBlock(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IscsiPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "iqn": "iqn",
        "lun": "lun",
        "target_portal": "targetPortal",
        "chap_auth_discovery": "chapAuthDiscovery",
        "chap_auth_session": "chapAuthSession",
        "fs_type": "fsType",
        "initiator_name": "initiatorName",
        "iscsi_interface": "iscsiInterface",
        "portals": "portals",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
    },
)
class IscsiPersistentVolumeSource:
    def __init__(
        self,
        *,
        iqn: builtins.str,
        lun: jsii.Number,
        target_portal: builtins.str,
        chap_auth_discovery: typing.Optional[builtins.bool] = None,
        chap_auth_session: typing.Optional[builtins.bool] = None,
        fs_type: typing.Optional[builtins.str] = None,
        initiator_name: typing.Optional[builtins.str] = None,
        iscsi_interface: typing.Optional[builtins.str] = None,
        portals: typing.Optional[typing.Sequence[builtins.str]] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ISCSIPersistentVolumeSource represents an ISCSI disk.

        ISCSI volumes can only be mounted as read/write once. ISCSI volumes support ownership management and SELinux relabeling.

        :param iqn: Target iSCSI Qualified Name.
        :param lun: iSCSI Target Lun number.
        :param target_portal: iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).
        :param chap_auth_discovery: whether support iSCSI Discovery CHAP authentication.
        :param chap_auth_session: whether support iSCSI Session CHAP authentication.
        :param fs_type: Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
        :param initiator_name: Custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection.
        :param iscsi_interface: iSCSI Interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). Default: default' (tcp).
        :param portals: iSCSI Target Portal List. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).
        :param read_only: ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. Default: false.
        :param secret_ref: CHAP Secret for iSCSI target and initiator authentication.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = SecretReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                iqn: builtins.str,
                lun: jsii.Number,
                target_portal: builtins.str,
                chap_auth_discovery: typing.Optional[builtins.bool] = None,
                chap_auth_session: typing.Optional[builtins.bool] = None,
                fs_type: typing.Optional[builtins.str] = None,
                initiator_name: typing.Optional[builtins.str] = None,
                iscsi_interface: typing.Optional[builtins.str] = None,
                portals: typing.Optional[typing.Sequence[builtins.str]] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument iqn", value=iqn, expected_type=type_hints["iqn"])
            check_type(argname="argument lun", value=lun, expected_type=type_hints["lun"])
            check_type(argname="argument target_portal", value=target_portal, expected_type=type_hints["target_portal"])
            check_type(argname="argument chap_auth_discovery", value=chap_auth_discovery, expected_type=type_hints["chap_auth_discovery"])
            check_type(argname="argument chap_auth_session", value=chap_auth_session, expected_type=type_hints["chap_auth_session"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument initiator_name", value=initiator_name, expected_type=type_hints["initiator_name"])
            check_type(argname="argument iscsi_interface", value=iscsi_interface, expected_type=type_hints["iscsi_interface"])
            check_type(argname="argument portals", value=portals, expected_type=type_hints["portals"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "iqn": iqn,
            "lun": lun,
            "target_portal": target_portal,
        }
        if chap_auth_discovery is not None:
            self._values["chap_auth_discovery"] = chap_auth_discovery
        if chap_auth_session is not None:
            self._values["chap_auth_session"] = chap_auth_session
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if initiator_name is not None:
            self._values["initiator_name"] = initiator_name
        if iscsi_interface is not None:
            self._values["iscsi_interface"] = iscsi_interface
        if portals is not None:
            self._values["portals"] = portals
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def iqn(self) -> builtins.str:
        '''Target iSCSI Qualified Name.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#iqn
        '''
        result = self._values.get("iqn")
        assert result is not None, "Required property 'iqn' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def lun(self) -> jsii.Number:
        '''iSCSI Target Lun number.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#lun
        '''
        result = self._values.get("lun")
        assert result is not None, "Required property 'lun' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def target_portal(self) -> builtins.str:
        '''iSCSI Target Portal.

        The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#targetPortal
        '''
        result = self._values.get("target_portal")
        assert result is not None, "Required property 'target_portal' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def chap_auth_discovery(self) -> typing.Optional[builtins.bool]:
        '''whether support iSCSI Discovery CHAP authentication.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#chapAuthDiscovery
        '''
        result = self._values.get("chap_auth_discovery")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def chap_auth_session(self) -> typing.Optional[builtins.bool]:
        '''whether support iSCSI Session CHAP authentication.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#chapAuthSession
        '''
        result = self._values.get("chap_auth_session")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type of the volume that you want to mount.

        Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def initiator_name(self) -> typing.Optional[builtins.str]:
        '''Custom iSCSI Initiator Name.

        If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#initiatorName
        '''
        result = self._values.get("initiator_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def iscsi_interface(self) -> typing.Optional[builtins.str]:
        '''iSCSI Interface Name that uses an iSCSI transport.

        Defaults to 'default' (tcp).

        :default: default' (tcp).

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#iscsiInterface
        '''
        result = self._values.get("iscsi_interface")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def portals(self) -> typing.Optional[typing.List[builtins.str]]:
        '''iSCSI Target Portal List.

        The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#portals
        '''
        result = self._values.get("portals")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the ReadOnly setting in VolumeMounts.

        Defaults to false.

        :default: false.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["SecretReference"]:
        '''CHAP Secret for iSCSI target and initiator authentication.

        :schema: io.k8s.api.core.v1.ISCSIPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IscsiPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.IscsiVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "iqn": "iqn",
        "lun": "lun",
        "target_portal": "targetPortal",
        "chap_auth_discovery": "chapAuthDiscovery",
        "chap_auth_session": "chapAuthSession",
        "fs_type": "fsType",
        "initiator_name": "initiatorName",
        "iscsi_interface": "iscsiInterface",
        "portals": "portals",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
    },
)
class IscsiVolumeSource:
    def __init__(
        self,
        *,
        iqn: builtins.str,
        lun: jsii.Number,
        target_portal: builtins.str,
        chap_auth_discovery: typing.Optional[builtins.bool] = None,
        chap_auth_session: typing.Optional[builtins.bool] = None,
        fs_type: typing.Optional[builtins.str] = None,
        initiator_name: typing.Optional[builtins.str] = None,
        iscsi_interface: typing.Optional[builtins.str] = None,
        portals: typing.Optional[typing.Sequence[builtins.str]] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents an ISCSI disk.

        ISCSI volumes can only be mounted as read/write once. ISCSI volumes support ownership management and SELinux relabeling.

        :param iqn: Target iSCSI Qualified Name.
        :param lun: iSCSI Target Lun number.
        :param target_portal: iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).
        :param chap_auth_discovery: whether support iSCSI Discovery CHAP authentication.
        :param chap_auth_session: whether support iSCSI Session CHAP authentication.
        :param fs_type: Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
        :param initiator_name: Custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection.
        :param iscsi_interface: iSCSI Interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). Default: default' (tcp).
        :param portals: iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).
        :param read_only: ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. Default: false.
        :param secret_ref: CHAP Secret for iSCSI target and initiator authentication.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                iqn: builtins.str,
                lun: jsii.Number,
                target_portal: builtins.str,
                chap_auth_discovery: typing.Optional[builtins.bool] = None,
                chap_auth_session: typing.Optional[builtins.bool] = None,
                fs_type: typing.Optional[builtins.str] = None,
                initiator_name: typing.Optional[builtins.str] = None,
                iscsi_interface: typing.Optional[builtins.str] = None,
                portals: typing.Optional[typing.Sequence[builtins.str]] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument iqn", value=iqn, expected_type=type_hints["iqn"])
            check_type(argname="argument lun", value=lun, expected_type=type_hints["lun"])
            check_type(argname="argument target_portal", value=target_portal, expected_type=type_hints["target_portal"])
            check_type(argname="argument chap_auth_discovery", value=chap_auth_discovery, expected_type=type_hints["chap_auth_discovery"])
            check_type(argname="argument chap_auth_session", value=chap_auth_session, expected_type=type_hints["chap_auth_session"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument initiator_name", value=initiator_name, expected_type=type_hints["initiator_name"])
            check_type(argname="argument iscsi_interface", value=iscsi_interface, expected_type=type_hints["iscsi_interface"])
            check_type(argname="argument portals", value=portals, expected_type=type_hints["portals"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
        self._values: typing.Dict[str, typing.Any] = {
            "iqn": iqn,
            "lun": lun,
            "target_portal": target_portal,
        }
        if chap_auth_discovery is not None:
            self._values["chap_auth_discovery"] = chap_auth_discovery
        if chap_auth_session is not None:
            self._values["chap_auth_session"] = chap_auth_session
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if initiator_name is not None:
            self._values["initiator_name"] = initiator_name
        if iscsi_interface is not None:
            self._values["iscsi_interface"] = iscsi_interface
        if portals is not None:
            self._values["portals"] = portals
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref

    @builtins.property
    def iqn(self) -> builtins.str:
        '''Target iSCSI Qualified Name.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#iqn
        '''
        result = self._values.get("iqn")
        assert result is not None, "Required property 'iqn' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def lun(self) -> jsii.Number:
        '''iSCSI Target Lun number.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#lun
        '''
        result = self._values.get("lun")
        assert result is not None, "Required property 'lun' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def target_portal(self) -> builtins.str:
        '''iSCSI Target Portal.

        The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#targetPortal
        '''
        result = self._values.get("target_portal")
        assert result is not None, "Required property 'target_portal' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def chap_auth_discovery(self) -> typing.Optional[builtins.bool]:
        '''whether support iSCSI Discovery CHAP authentication.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#chapAuthDiscovery
        '''
        result = self._values.get("chap_auth_discovery")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def chap_auth_session(self) -> typing.Optional[builtins.bool]:
        '''whether support iSCSI Session CHAP authentication.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#chapAuthSession
        '''
        result = self._values.get("chap_auth_session")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type of the volume that you want to mount.

        Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def initiator_name(self) -> typing.Optional[builtins.str]:
        '''Custom iSCSI Initiator Name.

        If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#initiatorName
        '''
        result = self._values.get("initiator_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def iscsi_interface(self) -> typing.Optional[builtins.str]:
        '''iSCSI Interface Name that uses an iSCSI transport.

        Defaults to 'default' (tcp).

        :default: default' (tcp).

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#iscsiInterface
        '''
        result = self._values.get("iscsi_interface")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def portals(self) -> typing.Optional[typing.List[builtins.str]]:
        '''iSCSI Target Portal List.

        The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#portals
        '''
        result = self._values.get("portals")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the ReadOnly setting in VolumeMounts.

        Defaults to false.

        :default: false.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["LocalObjectReference"]:
        '''CHAP Secret for iSCSI target and initiator authentication.

        :schema: io.k8s.api.core.v1.ISCSIVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["LocalObjectReference"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "IscsiVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.JobSpec",
    jsii_struct_bases=[],
    name_mapping={
        "template": "template",
        "active_deadline_seconds": "activeDeadlineSeconds",
        "backoff_limit": "backoffLimit",
        "completion_mode": "completionMode",
        "completions": "completions",
        "manual_selector": "manualSelector",
        "parallelism": "parallelism",
        "selector": "selector",
        "suspend": "suspend",
        "ttl_seconds_after_finished": "ttlSecondsAfterFinished",
    },
)
class JobSpec:
    def __init__(
        self,
        *,
        template: typing.Union["PodTemplateSpec", typing.Dict[str, typing.Any]],
        active_deadline_seconds: typing.Optional[jsii.Number] = None,
        backoff_limit: typing.Optional[jsii.Number] = None,
        completion_mode: typing.Optional[builtins.str] = None,
        completions: typing.Optional[jsii.Number] = None,
        manual_selector: typing.Optional[builtins.bool] = None,
        parallelism: typing.Optional[jsii.Number] = None,
        selector: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
        suspend: typing.Optional[builtins.bool] = None,
        ttl_seconds_after_finished: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''JobSpec describes how the job execution will look like.

        :param template: Describes the pod that will be created when executing a job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
        :param active_deadline_seconds: Specifies the duration in seconds relative to the startTime that the job may be continuously active before the system tries to terminate it; value must be positive integer. If a Job is suspended (at creation or through an update), this timer will effectively be stopped and reset when the Job is resumed again.
        :param backoff_limit: Specifies the number of retries before marking this job failed. Defaults to 6 Default: 6
        :param completion_mode: CompletionMode specifies how Pod completions are tracked. It can be ``NonIndexed`` (default) or ``Indexed``. ``NonIndexed`` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other. ``Indexed`` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. The Job is considered complete when there is one successfully completed Pod for each index. When value is ``Indexed``, .spec.completions must be specified and ``.spec.parallelism`` must be less than or equal to 10^5. In addition, The Pod name takes the form ``$(job-name)-$(index)-$(random-string)``, the Pod hostname takes the form ``$(job-name)-$(index)``. This field is beta-level. More completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, the controller skips updates for the Job.
        :param completions: Specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
        :param manual_selector: manualSelector controls generation of pod labels and pod selectors. Leave ``manualSelector`` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see ``manualSelector=true`` in jobs that were created with the old ``extensions/v1beta1`` API. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector
        :param parallelism: Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
        :param selector: A label query over pods that should match the pod count. Normally, the system sets this field for you. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
        :param suspend: Suspend specifies whether the Job controller should create Pods or not. If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false. This field is beta-level, gated by SuspendJob feature flag (enabled by default). Default: false.
        :param ttl_seconds_after_finished: ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.

        :schema: io.k8s.api.batch.v1.JobSpec
        '''
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                template: typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]],
                active_deadline_seconds: typing.Optional[jsii.Number] = None,
                backoff_limit: typing.Optional[jsii.Number] = None,
                completion_mode: typing.Optional[builtins.str] = None,
                completions: typing.Optional[jsii.Number] = None,
                manual_selector: typing.Optional[builtins.bool] = None,
                parallelism: typing.Optional[jsii.Number] = None,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                suspend: typing.Optional[builtins.bool] = None,
                ttl_seconds_after_finished: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
            check_type(argname="argument active_deadline_seconds", value=active_deadline_seconds, expected_type=type_hints["active_deadline_seconds"])
            check_type(argname="argument backoff_limit", value=backoff_limit, expected_type=type_hints["backoff_limit"])
            check_type(argname="argument completion_mode", value=completion_mode, expected_type=type_hints["completion_mode"])
            check_type(argname="argument completions", value=completions, expected_type=type_hints["completions"])
            check_type(argname="argument manual_selector", value=manual_selector, expected_type=type_hints["manual_selector"])
            check_type(argname="argument parallelism", value=parallelism, expected_type=type_hints["parallelism"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument suspend", value=suspend, expected_type=type_hints["suspend"])
            check_type(argname="argument ttl_seconds_after_finished", value=ttl_seconds_after_finished, expected_type=type_hints["ttl_seconds_after_finished"])
        self._values: typing.Dict[str, typing.Any] = {
            "template": template,
        }
        if active_deadline_seconds is not None:
            self._values["active_deadline_seconds"] = active_deadline_seconds
        if backoff_limit is not None:
            self._values["backoff_limit"] = backoff_limit
        if completion_mode is not None:
            self._values["completion_mode"] = completion_mode
        if completions is not None:
            self._values["completions"] = completions
        if manual_selector is not None:
            self._values["manual_selector"] = manual_selector
        if parallelism is not None:
            self._values["parallelism"] = parallelism
        if selector is not None:
            self._values["selector"] = selector
        if suspend is not None:
            self._values["suspend"] = suspend
        if ttl_seconds_after_finished is not None:
            self._values["ttl_seconds_after_finished"] = ttl_seconds_after_finished

    @builtins.property
    def template(self) -> "PodTemplateSpec":
        '''Describes the pod that will be created when executing a job.

        More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/

        :schema: io.k8s.api.batch.v1.JobSpec#template
        '''
        result = self._values.get("template")
        assert result is not None, "Required property 'template' is missing"
        return typing.cast("PodTemplateSpec", result)

    @builtins.property
    def active_deadline_seconds(self) -> typing.Optional[jsii.Number]:
        '''Specifies the duration in seconds relative to the startTime that the job may be continuously active before the system tries to terminate it;

        value must be positive integer. If a Job is suspended (at creation or through an update), this timer will effectively be stopped and reset when the Job is resumed again.

        :schema: io.k8s.api.batch.v1.JobSpec#activeDeadlineSeconds
        '''
        result = self._values.get("active_deadline_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def backoff_limit(self) -> typing.Optional[jsii.Number]:
        '''Specifies the number of retries before marking this job failed.

        Defaults to 6

        :default: 6

        :schema: io.k8s.api.batch.v1.JobSpec#backoffLimit
        '''
        result = self._values.get("backoff_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def completion_mode(self) -> typing.Optional[builtins.str]:
        '''CompletionMode specifies how Pod completions are tracked. It can be ``NonIndexed`` (default) or ``Indexed``.

        ``NonIndexed`` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other.

        ``Indexed`` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. The Job is considered complete when there is one successfully completed Pod for each index. When value is ``Indexed``, .spec.completions must be specified and ``.spec.parallelism`` must be less than or equal to 10^5. In addition, The Pod name takes the form ``$(job-name)-$(index)-$(random-string)``, the Pod hostname takes the form ``$(job-name)-$(index)``.

        This field is beta-level. More completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, the controller skips updates for the Job.

        :schema: io.k8s.api.batch.v1.JobSpec#completionMode
        '''
        result = self._values.get("completion_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def completions(self) -> typing.Optional[jsii.Number]:
        '''Specifies the desired number of successfully finished pods the job should be run with.

        Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value.  Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/

        :schema: io.k8s.api.batch.v1.JobSpec#completions
        '''
        result = self._values.get("completions")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def manual_selector(self) -> typing.Optional[builtins.bool]:
        '''manualSelector controls generation of pod labels and pod selectors.

        Leave ``manualSelector`` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template.  When true, the user is responsible for picking unique labels and specifying the selector.  Failure to pick a unique label may cause this and other jobs to not function correctly.  However, You may see ``manualSelector=true`` in jobs that were created with the old ``extensions/v1beta1`` API. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector

        :schema: io.k8s.api.batch.v1.JobSpec#manualSelector
        '''
        result = self._values.get("manual_selector")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def parallelism(self) -> typing.Optional[jsii.Number]:
        '''Specifies the maximum desired number of pods the job should run at any given time.

        The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/

        :schema: io.k8s.api.batch.v1.JobSpec#parallelism
        '''
        result = self._values.get("parallelism")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def selector(self) -> typing.Optional["LabelSelector"]:
        '''A label query over pods that should match the pod count.

        Normally, the system sets this field for you. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

        :schema: io.k8s.api.batch.v1.JobSpec#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional["LabelSelector"], result)

    @builtins.property
    def suspend(self) -> typing.Optional[builtins.bool]:
        '''Suspend specifies whether the Job controller should create Pods or not.

        If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false.

        This field is beta-level, gated by SuspendJob feature flag (enabled by default).

        :default: false.

        :schema: io.k8s.api.batch.v1.JobSpec#suspend
        '''
        result = self._values.get("suspend")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ttl_seconds_after_finished(self) -> typing.Optional[jsii.Number]:
        '''ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed).

        If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.

        :schema: io.k8s.api.batch.v1.JobSpec#ttlSecondsAfterFinished
        '''
        result = self._values.get("ttl_seconds_after_finished")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "JobSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.JobTemplateSpec",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class JobTemplateSpec:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''JobTemplateSpec describes the data a Job should have when created from a template.

        :param metadata: Standard object's metadata of the jobs created from this template. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the job. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1.JobTemplateSpec
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = JobSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata of the jobs created from this template.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.JobTemplateSpec#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[JobSpec]:
        '''Specification of the desired behavior of the job.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1.JobTemplateSpec#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[JobSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "JobTemplateSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.JobTemplateSpecV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class JobTemplateSpecV1Beta1:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''JobTemplateSpec describes the data a Job should have when created from a template.

        :param metadata: Standard object's metadata of the jobs created from this template. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the job. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1beta1.JobTemplateSpec
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = JobSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata of the jobs created from this template.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1beta1.JobTemplateSpec#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[JobSpec]:
        '''Specification of the desired behavior of the job.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1beta1.JobTemplateSpec#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[JobSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "JobTemplateSpecV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.JsonSchemaProps",
    jsii_struct_bases=[],
    name_mapping={
        "additional_items": "additionalItems",
        "additional_properties": "additionalProperties",
        "all_of": "allOf",
        "any_of": "anyOf",
        "default": "default",
        "definitions": "definitions",
        "dependencies": "dependencies",
        "description": "description",
        "enum": "enum",
        "example": "example",
        "exclusive_maximum": "exclusiveMaximum",
        "exclusive_minimum": "exclusiveMinimum",
        "external_docs": "externalDocs",
        "format": "format",
        "id": "id",
        "items": "items",
        "maximum": "maximum",
        "max_items": "maxItems",
        "max_length": "maxLength",
        "max_properties": "maxProperties",
        "minimum": "minimum",
        "min_items": "minItems",
        "min_length": "minLength",
        "min_properties": "minProperties",
        "multiple_of": "multipleOf",
        "not_": "not",
        "nullable": "nullable",
        "one_of": "oneOf",
        "pattern": "pattern",
        "pattern_properties": "patternProperties",
        "properties": "properties",
        "ref": "ref",
        "required": "required",
        "schema": "schema",
        "title": "title",
        "type": "type",
        "unique_items": "uniqueItems",
        "x_kubernetes_embedded_resource": "xKubernetesEmbeddedResource",
        "x_kubernetes_int_or_string": "xKubernetesIntOrString",
        "x_kubernetes_list_map_keys": "xKubernetesListMapKeys",
        "x_kubernetes_list_type": "xKubernetesListType",
        "x_kubernetes_map_type": "xKubernetesMapType",
        "x_kubernetes_preserve_unknown_fields": "xKubernetesPreserveUnknownFields",
        "x_kubernetes_validations": "xKubernetesValidations",
    },
)
class JsonSchemaProps:
    def __init__(
        self,
        *,
        additional_items: typing.Any = None,
        additional_properties: typing.Any = None,
        all_of: typing.Optional[typing.Sequence[typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]]] = None,
        any_of: typing.Optional[typing.Sequence[typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]]] = None,
        default: typing.Any = None,
        definitions: typing.Optional[typing.Mapping[builtins.str, typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]]] = None,
        dependencies: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        description: typing.Optional[builtins.str] = None,
        enum: typing.Optional[typing.Sequence[typing.Any]] = None,
        example: typing.Any = None,
        exclusive_maximum: typing.Optional[builtins.bool] = None,
        exclusive_minimum: typing.Optional[builtins.bool] = None,
        external_docs: typing.Optional[typing.Union[ExternalDocumentation, typing.Dict[str, typing.Any]]] = None,
        format: typing.Optional[builtins.str] = None,
        id: typing.Optional[builtins.str] = None,
        items: typing.Any = None,
        maximum: typing.Optional[jsii.Number] = None,
        max_items: typing.Optional[jsii.Number] = None,
        max_length: typing.Optional[jsii.Number] = None,
        max_properties: typing.Optional[jsii.Number] = None,
        minimum: typing.Optional[jsii.Number] = None,
        min_items: typing.Optional[jsii.Number] = None,
        min_length: typing.Optional[jsii.Number] = None,
        min_properties: typing.Optional[jsii.Number] = None,
        multiple_of: typing.Optional[jsii.Number] = None,
        not_: typing.Optional[typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]] = None,
        nullable: typing.Optional[builtins.bool] = None,
        one_of: typing.Optional[typing.Sequence[typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]]] = None,
        pattern: typing.Optional[builtins.str] = None,
        pattern_properties: typing.Optional[typing.Mapping[builtins.str, typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]]] = None,
        properties: typing.Optional[typing.Mapping[builtins.str, typing.Union["JsonSchemaProps", typing.Dict[str, typing.Any]]]] = None,
        ref: typing.Optional[builtins.str] = None,
        required: typing.Optional[typing.Sequence[builtins.str]] = None,
        schema: typing.Optional[builtins.str] = None,
        title: typing.Optional[builtins.str] = None,
        type: typing.Optional[builtins.str] = None,
        unique_items: typing.Optional[builtins.bool] = None,
        x_kubernetes_embedded_resource: typing.Optional[builtins.bool] = None,
        x_kubernetes_int_or_string: typing.Optional[builtins.bool] = None,
        x_kubernetes_list_map_keys: typing.Optional[typing.Sequence[builtins.str]] = None,
        x_kubernetes_list_type: typing.Optional[builtins.str] = None,
        x_kubernetes_map_type: typing.Optional[builtins.str] = None,
        x_kubernetes_preserve_unknown_fields: typing.Optional[builtins.bool] = None,
        x_kubernetes_validations: typing.Optional[typing.Sequence[typing.Union["ValidationRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).

        :param additional_items: 
        :param additional_properties: 
        :param all_of: 
        :param any_of: 
        :param default: default is a default value for undefined object fields. Defaulting is a beta feature under the CustomResourceDefaulting feature gate. Defaulting requires spec.preserveUnknownFields to be false.
        :param definitions: 
        :param dependencies: 
        :param description: 
        :param enum: 
        :param example: 
        :param exclusive_maximum: 
        :param exclusive_minimum: 
        :param external_docs: 
        :param format: format is an OpenAPI v3 format string. Unknown formats are ignored. The following formats are validated:. - bsonobjectid: a bson object ID, i.e. a 24 characters hex string - uri: an URI as parsed by Golang net/url.ParseRequestURI - email: an email address as parsed by Golang net/mail.ParseAddress - hostname: a valid representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034]. - ipv4: an IPv4 IP as parsed by Golang net.ParseIP - ipv6: an IPv6 IP as parsed by Golang net.ParseIP - cidr: a CIDR as parsed by Golang net.ParseCIDR - mac: a MAC address as parsed by Golang net.ParseMAC - uuid: an UUID that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid3: an UUID3 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid4: an UUID4 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - uuid5: an UUID5 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - isbn: an ISBN10 or ISBN13 number string like "0321751043" or "978-0321751041" - isbn10: an ISBN10 number string like "0321751043" - isbn13: an ISBN13 number string like "978-0321751041" - creditcard: a credit card number defined by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$ with any non digit characters mixed in - ssn: a U.S. social security number following the regex ^\\d{3}[- ]?\\d{2}[- ]?\\d{4}$ - hexcolor: an hexadecimal color code like "#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$ - rgbcolor: an RGB color code like rgb like "rgb(255,255,2559" - byte: base64 encoded binary data - password: any kind of string - date: a date string like "2006-01-02" as defined by full-date in RFC3339 - duration: a duration string like "22 ns" as parsed by Golang time.ParseDuration or compatible with Scala duration format - datetime: a date time string like "2014-12-15T19:30:20.000Z" as defined by date-time in RFC3339.
        :param id: 
        :param items: 
        :param maximum: 
        :param max_items: 
        :param max_length: 
        :param max_properties: 
        :param minimum: 
        :param min_items: 
        :param min_length: 
        :param min_properties: 
        :param multiple_of: 
        :param not_: 
        :param nullable: 
        :param one_of: 
        :param pattern: 
        :param pattern_properties: 
        :param properties: 
        :param ref: 
        :param required: 
        :param schema: 
        :param title: 
        :param type: 
        :param unique_items: 
        :param x_kubernetes_embedded_resource: x-kubernetes-embedded-resource defines that the value is an embedded Kubernetes runtime.Object, with TypeMeta and ObjectMeta. The type must be object. It is allowed to further restrict the embedded object. kind, apiVersion and metadata are validated automatically. x-kubernetes-preserve-unknown-fields is allowed to be true, but does not have to be if the object is fully specified (up to kind, apiVersion, metadata).
        :param x_kubernetes_int_or_string: x-kubernetes-int-or-string specifies that this value is either an integer or a string. If this is true, an empty type is allowed and type as child of anyOf is permitted if following one of the following patterns: 1. anyOf: - type: integer - type: string 2. allOf: - anyOf: - type: integer - type: string - ... zero or more
        :param x_kubernetes_list_map_keys: x-kubernetes-list-map-keys annotates an array with the x-kubernetes-list-type ``map`` by specifying the keys used as the index of the map. This tag MUST only be used on lists that have the "x-kubernetes-list-type" extension set to "map". Also, the values specified for this attribute must be a scalar typed field of the child structure (no nesting is supported). The properties specified must either be required or have a default value, to ensure those properties are present for all list items.
        :param x_kubernetes_list_type: x-kubernetes-list-type annotates an array to further describe its topology. This extension must only be used on lists and may have 3 possible values: 1. ``atomic``: the list is treated as a single entity, like a scalar. Atomic lists will be entirely replaced when updated. This extension may be used on any type of list (struct, scalar, ...). 2. ``set``: Sets are lists that must not have multiple items with the same value. Each value must be a scalar, an object with x-kubernetes-map-type ``atomic`` or an array with x-kubernetes-list-type ``atomic``. 3. ``map``: These lists are like maps in that their elements have a non-index key used to identify them. Order is preserved upon merge. The map tag must only be used on a list with elements of type object. Defaults to atomic for arrays. Default: atomic for arrays.
        :param x_kubernetes_map_type: x-kubernetes-map-type annotates an object to further describe its topology. This extension must only be used when type is object and may have 2 possible values: 1. ``granular``: These maps are actual maps (key-value pairs) and each fields are independent from each other (they can each be manipulated by separate actors). This is the default behaviour for all maps. 2. ``atomic``: the list is treated as a single entity, like a scalar. Atomic maps will be entirely replaced when updated.
        :param x_kubernetes_preserve_unknown_fields: x-kubernetes-preserve-unknown-fields stops the API server decoding step from pruning fields which are not specified in the validation schema. This affects fields recursively, but switches back to normal pruning behaviour if nested properties or additionalProperties are specified in the schema. This can either be true or undefined. False is forbidden.
        :param x_kubernetes_validations: x-kubernetes-validations describes a list of validation rules written in the CEL expression language. This field is an alpha-level. Using this field requires the feature gate ``CustomResourceValidationExpressions`` to be enabled.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps
        '''
        if isinstance(external_docs, dict):
            external_docs = ExternalDocumentation(**external_docs)
        if isinstance(not_, dict):
            not_ = JsonSchemaProps(**not_)
        if __debug__:
            def stub(
                *,
                additional_items: typing.Any = None,
                additional_properties: typing.Any = None,
                all_of: typing.Optional[typing.Sequence[typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]]] = None,
                any_of: typing.Optional[typing.Sequence[typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]]] = None,
                default: typing.Any = None,
                definitions: typing.Optional[typing.Mapping[builtins.str, typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]]] = None,
                dependencies: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
                description: typing.Optional[builtins.str] = None,
                enum: typing.Optional[typing.Sequence[typing.Any]] = None,
                example: typing.Any = None,
                exclusive_maximum: typing.Optional[builtins.bool] = None,
                exclusive_minimum: typing.Optional[builtins.bool] = None,
                external_docs: typing.Optional[typing.Union[ExternalDocumentation, typing.Dict[str, typing.Any]]] = None,
                format: typing.Optional[builtins.str] = None,
                id: typing.Optional[builtins.str] = None,
                items: typing.Any = None,
                maximum: typing.Optional[jsii.Number] = None,
                max_items: typing.Optional[jsii.Number] = None,
                max_length: typing.Optional[jsii.Number] = None,
                max_properties: typing.Optional[jsii.Number] = None,
                minimum: typing.Optional[jsii.Number] = None,
                min_items: typing.Optional[jsii.Number] = None,
                min_length: typing.Optional[jsii.Number] = None,
                min_properties: typing.Optional[jsii.Number] = None,
                multiple_of: typing.Optional[jsii.Number] = None,
                not_: typing.Optional[typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]] = None,
                nullable: typing.Optional[builtins.bool] = None,
                one_of: typing.Optional[typing.Sequence[typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]]] = None,
                pattern: typing.Optional[builtins.str] = None,
                pattern_properties: typing.Optional[typing.Mapping[builtins.str, typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]]] = None,
                properties: typing.Optional[typing.Mapping[builtins.str, typing.Union[JsonSchemaProps, typing.Dict[str, typing.Any]]]] = None,
                ref: typing.Optional[builtins.str] = None,
                required: typing.Optional[typing.Sequence[builtins.str]] = None,
                schema: typing.Optional[builtins.str] = None,
                title: typing.Optional[builtins.str] = None,
                type: typing.Optional[builtins.str] = None,
                unique_items: typing.Optional[builtins.bool] = None,
                x_kubernetes_embedded_resource: typing.Optional[builtins.bool] = None,
                x_kubernetes_int_or_string: typing.Optional[builtins.bool] = None,
                x_kubernetes_list_map_keys: typing.Optional[typing.Sequence[builtins.str]] = None,
                x_kubernetes_list_type: typing.Optional[builtins.str] = None,
                x_kubernetes_map_type: typing.Optional[builtins.str] = None,
                x_kubernetes_preserve_unknown_fields: typing.Optional[builtins.bool] = None,
                x_kubernetes_validations: typing.Optional[typing.Sequence[typing.Union[ValidationRule, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument additional_items", value=additional_items, expected_type=type_hints["additional_items"])
            check_type(argname="argument additional_properties", value=additional_properties, expected_type=type_hints["additional_properties"])
            check_type(argname="argument all_of", value=all_of, expected_type=type_hints["all_of"])
            check_type(argname="argument any_of", value=any_of, expected_type=type_hints["any_of"])
            check_type(argname="argument default", value=default, expected_type=type_hints["default"])
            check_type(argname="argument definitions", value=definitions, expected_type=type_hints["definitions"])
            check_type(argname="argument dependencies", value=dependencies, expected_type=type_hints["dependencies"])
            check_type(argname="argument description", value=description, expected_type=type_hints["description"])
            check_type(argname="argument enum", value=enum, expected_type=type_hints["enum"])
            check_type(argname="argument example", value=example, expected_type=type_hints["example"])
            check_type(argname="argument exclusive_maximum", value=exclusive_maximum, expected_type=type_hints["exclusive_maximum"])
            check_type(argname="argument exclusive_minimum", value=exclusive_minimum, expected_type=type_hints["exclusive_minimum"])
            check_type(argname="argument external_docs", value=external_docs, expected_type=type_hints["external_docs"])
            check_type(argname="argument format", value=format, expected_type=type_hints["format"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument maximum", value=maximum, expected_type=type_hints["maximum"])
            check_type(argname="argument max_items", value=max_items, expected_type=type_hints["max_items"])
            check_type(argname="argument max_length", value=max_length, expected_type=type_hints["max_length"])
            check_type(argname="argument max_properties", value=max_properties, expected_type=type_hints["max_properties"])
            check_type(argname="argument minimum", value=minimum, expected_type=type_hints["minimum"])
            check_type(argname="argument min_items", value=min_items, expected_type=type_hints["min_items"])
            check_type(argname="argument min_length", value=min_length, expected_type=type_hints["min_length"])
            check_type(argname="argument min_properties", value=min_properties, expected_type=type_hints["min_properties"])
            check_type(argname="argument multiple_of", value=multiple_of, expected_type=type_hints["multiple_of"])
            check_type(argname="argument not_", value=not_, expected_type=type_hints["not_"])
            check_type(argname="argument nullable", value=nullable, expected_type=type_hints["nullable"])
            check_type(argname="argument one_of", value=one_of, expected_type=type_hints["one_of"])
            check_type(argname="argument pattern", value=pattern, expected_type=type_hints["pattern"])
            check_type(argname="argument pattern_properties", value=pattern_properties, expected_type=type_hints["pattern_properties"])
            check_type(argname="argument properties", value=properties, expected_type=type_hints["properties"])
            check_type(argname="argument ref", value=ref, expected_type=type_hints["ref"])
            check_type(argname="argument required", value=required, expected_type=type_hints["required"])
            check_type(argname="argument schema", value=schema, expected_type=type_hints["schema"])
            check_type(argname="argument title", value=title, expected_type=type_hints["title"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument unique_items", value=unique_items, expected_type=type_hints["unique_items"])
            check_type(argname="argument x_kubernetes_embedded_resource", value=x_kubernetes_embedded_resource, expected_type=type_hints["x_kubernetes_embedded_resource"])
            check_type(argname="argument x_kubernetes_int_or_string", value=x_kubernetes_int_or_string, expected_type=type_hints["x_kubernetes_int_or_string"])
            check_type(argname="argument x_kubernetes_list_map_keys", value=x_kubernetes_list_map_keys, expected_type=type_hints["x_kubernetes_list_map_keys"])
            check_type(argname="argument x_kubernetes_list_type", value=x_kubernetes_list_type, expected_type=type_hints["x_kubernetes_list_type"])
            check_type(argname="argument x_kubernetes_map_type", value=x_kubernetes_map_type, expected_type=type_hints["x_kubernetes_map_type"])
            check_type(argname="argument x_kubernetes_preserve_unknown_fields", value=x_kubernetes_preserve_unknown_fields, expected_type=type_hints["x_kubernetes_preserve_unknown_fields"])
            check_type(argname="argument x_kubernetes_validations", value=x_kubernetes_validations, expected_type=type_hints["x_kubernetes_validations"])
        self._values: typing.Dict[str, typing.Any] = {}
        if additional_items is not None:
            self._values["additional_items"] = additional_items
        if additional_properties is not None:
            self._values["additional_properties"] = additional_properties
        if all_of is not None:
            self._values["all_of"] = all_of
        if any_of is not None:
            self._values["any_of"] = any_of
        if default is not None:
            self._values["default"] = default
        if definitions is not None:
            self._values["definitions"] = definitions
        if dependencies is not None:
            self._values["dependencies"] = dependencies
        if description is not None:
            self._values["description"] = description
        if enum is not None:
            self._values["enum"] = enum
        if example is not None:
            self._values["example"] = example
        if exclusive_maximum is not None:
            self._values["exclusive_maximum"] = exclusive_maximum
        if exclusive_minimum is not None:
            self._values["exclusive_minimum"] = exclusive_minimum
        if external_docs is not None:
            self._values["external_docs"] = external_docs
        if format is not None:
            self._values["format"] = format
        if id is not None:
            self._values["id"] = id
        if items is not None:
            self._values["items"] = items
        if maximum is not None:
            self._values["maximum"] = maximum
        if max_items is not None:
            self._values["max_items"] = max_items
        if max_length is not None:
            self._values["max_length"] = max_length
        if max_properties is not None:
            self._values["max_properties"] = max_properties
        if minimum is not None:
            self._values["minimum"] = minimum
        if min_items is not None:
            self._values["min_items"] = min_items
        if min_length is not None:
            self._values["min_length"] = min_length
        if min_properties is not None:
            self._values["min_properties"] = min_properties
        if multiple_of is not None:
            self._values["multiple_of"] = multiple_of
        if not_ is not None:
            self._values["not_"] = not_
        if nullable is not None:
            self._values["nullable"] = nullable
        if one_of is not None:
            self._values["one_of"] = one_of
        if pattern is not None:
            self._values["pattern"] = pattern
        if pattern_properties is not None:
            self._values["pattern_properties"] = pattern_properties
        if properties is not None:
            self._values["properties"] = properties
        if ref is not None:
            self._values["ref"] = ref
        if required is not None:
            self._values["required"] = required
        if schema is not None:
            self._values["schema"] = schema
        if title is not None:
            self._values["title"] = title
        if type is not None:
            self._values["type"] = type
        if unique_items is not None:
            self._values["unique_items"] = unique_items
        if x_kubernetes_embedded_resource is not None:
            self._values["x_kubernetes_embedded_resource"] = x_kubernetes_embedded_resource
        if x_kubernetes_int_or_string is not None:
            self._values["x_kubernetes_int_or_string"] = x_kubernetes_int_or_string
        if x_kubernetes_list_map_keys is not None:
            self._values["x_kubernetes_list_map_keys"] = x_kubernetes_list_map_keys
        if x_kubernetes_list_type is not None:
            self._values["x_kubernetes_list_type"] = x_kubernetes_list_type
        if x_kubernetes_map_type is not None:
            self._values["x_kubernetes_map_type"] = x_kubernetes_map_type
        if x_kubernetes_preserve_unknown_fields is not None:
            self._values["x_kubernetes_preserve_unknown_fields"] = x_kubernetes_preserve_unknown_fields
        if x_kubernetes_validations is not None:
            self._values["x_kubernetes_validations"] = x_kubernetes_validations

    @builtins.property
    def additional_items(self) -> typing.Any:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#additionalItems
        '''
        result = self._values.get("additional_items")
        return typing.cast(typing.Any, result)

    @builtins.property
    def additional_properties(self) -> typing.Any:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#additionalProperties
        '''
        result = self._values.get("additional_properties")
        return typing.cast(typing.Any, result)

    @builtins.property
    def all_of(self) -> typing.Optional[typing.List["JsonSchemaProps"]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#allOf
        '''
        result = self._values.get("all_of")
        return typing.cast(typing.Optional[typing.List["JsonSchemaProps"]], result)

    @builtins.property
    def any_of(self) -> typing.Optional[typing.List["JsonSchemaProps"]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#anyOf
        '''
        result = self._values.get("any_of")
        return typing.cast(typing.Optional[typing.List["JsonSchemaProps"]], result)

    @builtins.property
    def default(self) -> typing.Any:
        '''default is a default value for undefined object fields.

        Defaulting is a beta feature under the CustomResourceDefaulting feature gate. Defaulting requires spec.preserveUnknownFields to be false.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#default
        '''
        result = self._values.get("default")
        return typing.cast(typing.Any, result)

    @builtins.property
    def definitions(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, "JsonSchemaProps"]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#definitions
        '''
        result = self._values.get("definitions")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "JsonSchemaProps"]], result)

    @builtins.property
    def dependencies(self) -> typing.Optional[typing.Mapping[builtins.str, typing.Any]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#dependencies
        '''
        result = self._values.get("dependencies")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, typing.Any]], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def enum(self) -> typing.Optional[typing.List[typing.Any]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#enum
        '''
        result = self._values.get("enum")
        return typing.cast(typing.Optional[typing.List[typing.Any]], result)

    @builtins.property
    def example(self) -> typing.Any:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#example
        '''
        result = self._values.get("example")
        return typing.cast(typing.Any, result)

    @builtins.property
    def exclusive_maximum(self) -> typing.Optional[builtins.bool]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#exclusiveMaximum
        '''
        result = self._values.get("exclusive_maximum")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def exclusive_minimum(self) -> typing.Optional[builtins.bool]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#exclusiveMinimum
        '''
        result = self._values.get("exclusive_minimum")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def external_docs(self) -> typing.Optional[ExternalDocumentation]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#externalDocs
        '''
        result = self._values.get("external_docs")
        return typing.cast(typing.Optional[ExternalDocumentation], result)

    @builtins.property
    def format(self) -> typing.Optional[builtins.str]:
        '''format is an OpenAPI v3 format string. Unknown formats are ignored. The following formats are validated:.

        - bsonobjectid: a bson object ID, i.e. a 24 characters hex string - uri: an URI as parsed by Golang net/url.ParseRequestURI - email: an email address as parsed by Golang net/mail.ParseAddress - hostname: a valid representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034]. - ipv4: an IPv4 IP as parsed by Golang net.ParseIP - ipv6: an IPv6 IP as parsed by Golang net.ParseIP - cidr: a CIDR as parsed by Golang net.ParseCIDR - mac: a MAC address as parsed by Golang net.ParseMAC - uuid: an UUID that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid3: an UUID3 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid4: an UUID4 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - uuid5: an UUID5 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - isbn: an ISBN10 or ISBN13 number string like "0321751043" or "978-0321751041" - isbn10: an ISBN10 number string like "0321751043" - isbn13: an ISBN13 number string like "978-0321751041" - creditcard: a credit card number defined by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$ with any non digit characters mixed in - ssn: a U.S. social security number following the regex ^\\d{3}[- ]?\\d{2}[- ]?\\d{4}$ - hexcolor: an hexadecimal color code like "#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$ - rgbcolor: an RGB color code like rgb like "rgb(255,255,2559" - byte: base64 encoded binary data - password: any kind of string - date: a date string like "2006-01-02" as defined by full-date in RFC3339 - duration: a duration string like "22 ns" as parsed by Golang time.ParseDuration or compatible with Scala duration format - datetime: a date time string like "2014-12-15T19:30:20.000Z" as defined by date-time in RFC3339.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#format
        '''
        result = self._values.get("format")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def id(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#id
        '''
        result = self._values.get("id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def items(self) -> typing.Any:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Any, result)

    @builtins.property
    def maximum(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#maximum
        '''
        result = self._values.get("maximum")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def max_items(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#maxItems
        '''
        result = self._values.get("max_items")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def max_length(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#maxLength
        '''
        result = self._values.get("max_length")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def max_properties(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#maxProperties
        '''
        result = self._values.get("max_properties")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def minimum(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#minimum
        '''
        result = self._values.get("minimum")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def min_items(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#minItems
        '''
        result = self._values.get("min_items")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def min_length(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#minLength
        '''
        result = self._values.get("min_length")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def min_properties(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#minProperties
        '''
        result = self._values.get("min_properties")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def multiple_of(self) -> typing.Optional[jsii.Number]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#multipleOf
        '''
        result = self._values.get("multiple_of")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def not_(self) -> typing.Optional["JsonSchemaProps"]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#not
        '''
        result = self._values.get("not_")
        return typing.cast(typing.Optional["JsonSchemaProps"], result)

    @builtins.property
    def nullable(self) -> typing.Optional[builtins.bool]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#nullable
        '''
        result = self._values.get("nullable")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def one_of(self) -> typing.Optional[typing.List["JsonSchemaProps"]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#oneOf
        '''
        result = self._values.get("one_of")
        return typing.cast(typing.Optional[typing.List["JsonSchemaProps"]], result)

    @builtins.property
    def pattern(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#pattern
        '''
        result = self._values.get("pattern")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def pattern_properties(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, "JsonSchemaProps"]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#patternProperties
        '''
        result = self._values.get("pattern_properties")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "JsonSchemaProps"]], result)

    @builtins.property
    def properties(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, "JsonSchemaProps"]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#properties
        '''
        result = self._values.get("properties")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "JsonSchemaProps"]], result)

    @builtins.property
    def ref(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#$ref
        '''
        result = self._values.get("ref")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def required(self) -> typing.Optional[typing.List[builtins.str]]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#required
        '''
        result = self._values.get("required")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def schema(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#$schema
        '''
        result = self._values.get("schema")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def title(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#title
        '''
        result = self._values.get("title")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def unique_items(self) -> typing.Optional[builtins.bool]:
        '''
        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#uniqueItems
        '''
        result = self._values.get("unique_items")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def x_kubernetes_embedded_resource(self) -> typing.Optional[builtins.bool]:
        '''x-kubernetes-embedded-resource defines that the value is an embedded Kubernetes runtime.Object, with TypeMeta and ObjectMeta. The type must be object. It is allowed to further restrict the embedded object. kind, apiVersion and metadata are validated automatically. x-kubernetes-preserve-unknown-fields is allowed to be true, but does not have to be if the object is fully specified (up to kind, apiVersion, metadata).

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-embedded-resource
        '''
        result = self._values.get("x_kubernetes_embedded_resource")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def x_kubernetes_int_or_string(self) -> typing.Optional[builtins.bool]:
        '''x-kubernetes-int-or-string specifies that this value is either an integer or a string.

        If this is true, an empty type is allowed and type as child of anyOf is permitted if following one of the following patterns:

        1. anyOf:

        - type: integer
        - type: string

        1. allOf:

        - anyOf:
        - type: integer
        - type: string
        - ... zero or more

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-int-or-string
        '''
        result = self._values.get("x_kubernetes_int_or_string")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def x_kubernetes_list_map_keys(self) -> typing.Optional[typing.List[builtins.str]]:
        '''x-kubernetes-list-map-keys annotates an array with the x-kubernetes-list-type ``map`` by specifying the keys used as the index of the map.

        This tag MUST only be used on lists that have the "x-kubernetes-list-type" extension set to "map". Also, the values specified for this attribute must be a scalar typed field of the child structure (no nesting is supported).

        The properties specified must either be required or have a default value, to ensure those properties are present for all list items.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-list-map-keys
        '''
        result = self._values.get("x_kubernetes_list_map_keys")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def x_kubernetes_list_type(self) -> typing.Optional[builtins.str]:
        '''x-kubernetes-list-type annotates an array to further describe its topology.

        This extension must only be used on lists and may have 3 possible values:

        1. ``atomic``: the list is treated as a single entity, like a scalar.
           Atomic lists will be entirely replaced when updated. This extension
           may be used on any type of list (struct, scalar, ...).
        2. ``set``:
           Sets are lists that must not have multiple items with the same value. Each
           value must be a scalar, an object with x-kubernetes-map-type ``atomic`` or an
           array with x-kubernetes-list-type ``atomic``.
        3. ``map``:
           These lists are like maps in that their elements have a non-index key
           used to identify them. Order is preserved upon merge. The map tag
           must only be used on a list with elements of type object.
           Defaults to atomic for arrays.

        :default: atomic for arrays.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-list-type
        '''
        result = self._values.get("x_kubernetes_list_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def x_kubernetes_map_type(self) -> typing.Optional[builtins.str]:
        '''x-kubernetes-map-type annotates an object to further describe its topology.

        This extension must only be used when type is object and may have 2 possible values:

        1. ``granular``:
           These maps are actual maps (key-value pairs) and each fields are independent
           from each other (they can each be manipulated by separate actors). This is
           the default behaviour for all maps.
        2. ``atomic``: the list is treated as a single entity, like a scalar.
           Atomic maps will be entirely replaced when updated.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-map-type
        '''
        result = self._values.get("x_kubernetes_map_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def x_kubernetes_preserve_unknown_fields(self) -> typing.Optional[builtins.bool]:
        '''x-kubernetes-preserve-unknown-fields stops the API server decoding step from pruning fields which are not specified in the validation schema.

        This affects fields recursively, but switches back to normal pruning behaviour if nested properties or additionalProperties are specified in the schema. This can either be true or undefined. False is forbidden.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-preserve-unknown-fields
        '''
        result = self._values.get("x_kubernetes_preserve_unknown_fields")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def x_kubernetes_validations(
        self,
    ) -> typing.Optional[typing.List["ValidationRule"]]:
        '''x-kubernetes-validations describes a list of validation rules written in the CEL expression language.

        This field is an alpha-level. Using this field requires the feature gate ``CustomResourceValidationExpressions`` to be enabled.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps#x-kubernetes-validations
        '''
        result = self._values.get("x_kubernetes_validations")
        return typing.cast(typing.Optional[typing.List["ValidationRule"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "JsonSchemaProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KeyToPath",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "path": "path", "mode": "mode"},
)
class KeyToPath:
    def __init__(
        self,
        *,
        key: builtins.str,
        path: builtins.str,
        mode: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Maps a string key to a path within a volume.

        :param key: The key to project.
        :param path: The relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'.
        :param mode: Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.KeyToPath
        '''
        if __debug__:
            def stub(
                *,
                key: builtins.str,
                path: builtins.str,
                mode: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument mode", value=mode, expected_type=type_hints["mode"])
        self._values: typing.Dict[str, typing.Any] = {
            "key": key,
            "path": path,
        }
        if mode is not None:
            self._values["mode"] = mode

    @builtins.property
    def key(self) -> builtins.str:
        '''The key to project.

        :schema: io.k8s.api.core.v1.KeyToPath#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def path(self) -> builtins.str:
        '''The relative path of the file to map the key to.

        May not be an absolute path. May not contain the path element '..'. May not start with the string '..'.

        :schema: io.k8s.api.core.v1.KeyToPath#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def mode(self) -> typing.Optional[jsii.Number]:
        '''Optional: mode bits used to set permissions on this file.

        Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.KeyToPath#mode
        '''
        result = self._values.get("mode")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KeyToPath(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeApiService(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeApiService",
):
    '''APIService represents a server for a particular GroupVersion.

    Name must be "version.group".

    :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[ApiServiceSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec contains information for locating and communicating with a server.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ApiServiceSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeApiServiceProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[ApiServiceSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec contains information for locating and communicating with a server.
        '''
        props = KubeApiServiceProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeApiServiceList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeApiServiceList",
):
    '''APIServiceList is a list of APIService objects.

    :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeApiServiceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of APIService.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeApiServiceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeApiServiceListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeApiServiceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of APIService.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeApiServiceListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeApiServiceListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeApiServiceListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeApiServiceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''APIServiceList is a list of APIService objects.

        :param items: Items is the list of APIService.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeApiServiceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeApiServiceProps"]:
        '''Items is the list of APIService.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeApiServiceProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeApiServiceListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeApiServiceProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeApiServiceProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[ApiServiceSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''APIService represents a server for a particular GroupVersion.

        Name must be "version.group".

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec contains information for locating and communicating with a server.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = ApiServiceSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ApiServiceSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[ApiServiceSpec]:
        '''Spec contains information for locating and communicating with a server.

        :schema: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[ApiServiceSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeApiServiceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeBinding(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeBinding",
):
    '''Binding ties one object to another;

    for example, a pod is bound to a node by a scheduler. Deprecated in 1.7, please use the bindings subresource of pods instead.

    :schema: io.k8s.api.core.v1.Binding
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        target: typing.Union["ObjectReference", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Binding" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param target: The target object that you want to bind to the standard object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                target: typing.Union[ObjectReference, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeBindingProps(target=target, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        target: typing.Union["ObjectReference", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Binding".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param target: The target object that you want to bind to the standard object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeBindingProps(target=target, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Binding".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeBindingProps",
    jsii_struct_bases=[],
    name_mapping={"target": "target", "metadata": "metadata"},
)
class KubeBindingProps:
    def __init__(
        self,
        *,
        target: typing.Union["ObjectReference", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Binding ties one object to another;

        for example, a pod is bound to a node by a scheduler. Deprecated in 1.7, please use the bindings subresource of pods instead.

        :param target: The target object that you want to bind to the standard object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Binding
        '''
        if isinstance(target, dict):
            target = ObjectReference(**target)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                target: typing.Union[ObjectReference, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "target": target,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def target(self) -> "ObjectReference":
        '''The target object that you want to bind to the standard object.

        :schema: io.k8s.api.core.v1.Binding#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast("ObjectReference", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Binding#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeBindingProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCertificateSigningRequest(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCertificateSigningRequest",
):
    '''CertificateSigningRequest objects provide a mechanism to obtain x509 certificates by submitting a certificate signing request, and having it asynchronously approved and issued.

    Kubelets use this API to obtain:

    1. client certificates to authenticate to kube-apiserver (with the "kubernetes.io/kube-apiserver-client-kubelet" signerName).
    2. serving certificates for TLS endpoints kube-apiserver can connect to securely (with the "kubernetes.io/kubelet-serving" signerName).

    This API can be used to request client certificates to authenticate to kube-apiserver (with the "kubernetes.io/kube-apiserver-client" signerName), or to obtain certificates from custom non-Kubernetes signers.

    :schema: io.k8s.api.certificates.v1.CertificateSigningRequest
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union[CertificateSigningRequestSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.certificates.v1.CertificateSigningRequest" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: spec contains the certificate request, and is immutable after creation. Only the request, signerName, expirationSeconds, and usages fields can be set on creation. Other fields are derived by Kubernetes and cannot be modified by users.
        :param metadata: 
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[CertificateSigningRequestSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCertificateSigningRequestProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union[CertificateSigningRequestSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.certificates.v1.CertificateSigningRequest".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: spec contains the certificate request, and is immutable after creation. Only the request, signerName, expirationSeconds, and usages fields can be set on creation. Other fields are derived by Kubernetes and cannot be modified by users.
        :param metadata: 
        '''
        props = KubeCertificateSigningRequestProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.certificates.v1.CertificateSigningRequest".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeCertificateSigningRequestList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCertificateSigningRequestList",
):
    '''CertificateSigningRequestList is a collection of CertificateSigningRequest objects.

    :schema: io.k8s.api.certificates.v1.CertificateSigningRequestList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCertificateSigningRequestProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.certificates.v1.CertificateSigningRequestList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is a collection of CertificateSigningRequest objects.
        :param metadata: 
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCertificateSigningRequestProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCertificateSigningRequestListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCertificateSigningRequestProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.certificates.v1.CertificateSigningRequestList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is a collection of CertificateSigningRequest objects.
        :param metadata: 
        '''
        props = KubeCertificateSigningRequestListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.certificates.v1.CertificateSigningRequestList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCertificateSigningRequestListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCertificateSigningRequestListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCertificateSigningRequestProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CertificateSigningRequestList is a collection of CertificateSigningRequest objects.

        :param items: items is a collection of CertificateSigningRequest objects.
        :param metadata: 

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCertificateSigningRequestProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCertificateSigningRequestProps"]:
        '''items is a collection of CertificateSigningRequest objects.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCertificateSigningRequestProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''
        :schema: io.k8s.api.certificates.v1.CertificateSigningRequestList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCertificateSigningRequestListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCertificateSigningRequestProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeCertificateSigningRequestProps:
    def __init__(
        self,
        *,
        spec: typing.Union[CertificateSigningRequestSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CertificateSigningRequest objects provide a mechanism to obtain x509 certificates by submitting a certificate signing request, and having it asynchronously approved and issued.

        Kubelets use this API to obtain:

        1. client certificates to authenticate to kube-apiserver (with the "kubernetes.io/kube-apiserver-client-kubelet" signerName).
        2. serving certificates for TLS endpoints kube-apiserver can connect to securely (with the "kubernetes.io/kubelet-serving" signerName).

        This API can be used to request client certificates to authenticate to kube-apiserver (with the "kubernetes.io/kube-apiserver-client" signerName), or to obtain certificates from custom non-Kubernetes signers.

        :param spec: spec contains the certificate request, and is immutable after creation. Only the request, signerName, expirationSeconds, and usages fields can be set on creation. Other fields are derived by Kubernetes and cannot be modified by users.
        :param metadata: 

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequest
        '''
        if isinstance(spec, dict):
            spec = CertificateSigningRequestSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[CertificateSigningRequestSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> CertificateSigningRequestSpec:
        '''spec contains the certificate request, and is immutable after creation.

        Only the request, signerName, expirationSeconds, and usages fields can be set on creation. Other fields are derived by Kubernetes and cannot be modified by users.

        :schema: io.k8s.api.certificates.v1.CertificateSigningRequest#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(CertificateSigningRequestSpec, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''
        :schema: io.k8s.api.certificates.v1.CertificateSigningRequest#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCertificateSigningRequestProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeClusterRole(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRole",
):
    '''ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.

    :schema: io.k8s.api.rbac.v1.ClusterRole
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        aggregation_rule: typing.Optional[typing.Union[AggregationRule, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.ClusterRole" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param aggregation_rule: AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be stomped by the controller.
        :param metadata: Standard object's metadata.
        :param rules: Rules holds all the PolicyRules for this ClusterRole.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                aggregation_rule: typing.Optional[typing.Union[AggregationRule, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[PolicyRule, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeClusterRoleProps(
            aggregation_rule=aggregation_rule, metadata=metadata, rules=rules
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        aggregation_rule: typing.Optional[typing.Union[AggregationRule, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.ClusterRole".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param aggregation_rule: AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be stomped by the controller.
        :param metadata: Standard object's metadata.
        :param rules: Rules holds all the PolicyRules for this ClusterRole.
        '''
        props = KubeClusterRoleProps(
            aggregation_rule=aggregation_rule, metadata=metadata, rules=rules
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.ClusterRole".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeClusterRoleBinding(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleBinding",
):
    '''ClusterRoleBinding references a ClusterRole, but not contain it.

    It can reference a ClusterRole in the global namespace, and adds who information via Subject.

    :schema: io.k8s.api.rbac.v1.ClusterRoleBinding
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        role_ref: typing.Union["RoleRef", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subjects: typing.Optional[typing.Sequence[typing.Union["Subject", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.ClusterRoleBinding" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param role_ref: RoleRef can only reference a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.
        :param metadata: Standard object's metadata.
        :param subjects: Subjects holds references to the objects the role applies to.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                role_ref: typing.Union[RoleRef, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                subjects: typing.Optional[typing.Sequence[typing.Union[Subject, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeClusterRoleBindingProps(
            role_ref=role_ref, metadata=metadata, subjects=subjects
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        role_ref: typing.Union["RoleRef", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subjects: typing.Optional[typing.Sequence[typing.Union["Subject", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.ClusterRoleBinding".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param role_ref: RoleRef can only reference a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.
        :param metadata: Standard object's metadata.
        :param subjects: Subjects holds references to the objects the role applies to.
        '''
        props = KubeClusterRoleBindingProps(
            role_ref=role_ref, metadata=metadata, subjects=subjects
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.ClusterRoleBinding".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeClusterRoleBindingList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleBindingList",
):
    '''ClusterRoleBindingList is a collection of ClusterRoleBindings.

    :schema: io.k8s.api.rbac.v1.ClusterRoleBindingList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeClusterRoleBindingProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.ClusterRoleBindingList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of ClusterRoleBindings.
        :param metadata: Standard object's metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeClusterRoleBindingProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeClusterRoleBindingListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeClusterRoleBindingProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.ClusterRoleBindingList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of ClusterRoleBindings.
        :param metadata: Standard object's metadata.
        '''
        props = KubeClusterRoleBindingListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.ClusterRoleBindingList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleBindingListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeClusterRoleBindingListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeClusterRoleBindingProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ClusterRoleBindingList is a collection of ClusterRoleBindings.

        :param items: Items is a list of ClusterRoleBindings.
        :param metadata: Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBindingList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeClusterRoleBindingProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeClusterRoleBindingProps"]:
        '''Items is a list of ClusterRoleBindings.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBindingList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeClusterRoleBindingProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBindingList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeClusterRoleBindingListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleBindingProps",
    jsii_struct_bases=[],
    name_mapping={
        "role_ref": "roleRef",
        "metadata": "metadata",
        "subjects": "subjects",
    },
)
class KubeClusterRoleBindingProps:
    def __init__(
        self,
        *,
        role_ref: typing.Union["RoleRef", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subjects: typing.Optional[typing.Sequence[typing.Union["Subject", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''ClusterRoleBinding references a ClusterRole, but not contain it.

        It can reference a ClusterRole in the global namespace, and adds who information via Subject.

        :param role_ref: RoleRef can only reference a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.
        :param metadata: Standard object's metadata.
        :param subjects: Subjects holds references to the objects the role applies to.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBinding
        '''
        if isinstance(role_ref, dict):
            role_ref = RoleRef(**role_ref)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                role_ref: typing.Union[RoleRef, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                subjects: typing.Optional[typing.Sequence[typing.Union[Subject, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument role_ref", value=role_ref, expected_type=type_hints["role_ref"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument subjects", value=subjects, expected_type=type_hints["subjects"])
        self._values: typing.Dict[str, typing.Any] = {
            "role_ref": role_ref,
        }
        if metadata is not None:
            self._values["metadata"] = metadata
        if subjects is not None:
            self._values["subjects"] = subjects

    @builtins.property
    def role_ref(self) -> "RoleRef":
        '''RoleRef can only reference a ClusterRole in the global namespace.

        If the RoleRef cannot be resolved, the Authorizer must return an error.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBinding#roleRef
        '''
        result = self._values.get("role_ref")
        assert result is not None, "Required property 'role_ref' is missing"
        return typing.cast("RoleRef", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBinding#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def subjects(self) -> typing.Optional[typing.List["Subject"]]:
        '''Subjects holds references to the objects the role applies to.

        :schema: io.k8s.api.rbac.v1.ClusterRoleBinding#subjects
        '''
        result = self._values.get("subjects")
        return typing.cast(typing.Optional[typing.List["Subject"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeClusterRoleBindingProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeClusterRoleList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleList",
):
    '''ClusterRoleList is a collection of ClusterRoles.

    :schema: io.k8s.api.rbac.v1.ClusterRoleList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeClusterRoleProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.ClusterRoleList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of ClusterRoles.
        :param metadata: Standard object's metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeClusterRoleProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeClusterRoleListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeClusterRoleProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.ClusterRoleList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of ClusterRoles.
        :param metadata: Standard object's metadata.
        '''
        props = KubeClusterRoleListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.ClusterRoleList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeClusterRoleListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeClusterRoleProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ClusterRoleList is a collection of ClusterRoles.

        :param items: Items is a list of ClusterRoles.
        :param metadata: Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.ClusterRoleList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeClusterRoleProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeClusterRoleProps"]:
        '''Items is a list of ClusterRoles.

        :schema: io.k8s.api.rbac.v1.ClusterRoleList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeClusterRoleProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.ClusterRoleList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeClusterRoleListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeClusterRoleProps",
    jsii_struct_bases=[],
    name_mapping={
        "aggregation_rule": "aggregationRule",
        "metadata": "metadata",
        "rules": "rules",
    },
)
class KubeClusterRoleProps:
    def __init__(
        self,
        *,
        aggregation_rule: typing.Optional[typing.Union[AggregationRule, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.

        :param aggregation_rule: AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be stomped by the controller.
        :param metadata: Standard object's metadata.
        :param rules: Rules holds all the PolicyRules for this ClusterRole.

        :schema: io.k8s.api.rbac.v1.ClusterRole
        '''
        if isinstance(aggregation_rule, dict):
            aggregation_rule = AggregationRule(**aggregation_rule)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                aggregation_rule: typing.Optional[typing.Union[AggregationRule, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[PolicyRule, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument aggregation_rule", value=aggregation_rule, expected_type=type_hints["aggregation_rule"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
        self._values: typing.Dict[str, typing.Any] = {}
        if aggregation_rule is not None:
            self._values["aggregation_rule"] = aggregation_rule
        if metadata is not None:
            self._values["metadata"] = metadata
        if rules is not None:
            self._values["rules"] = rules

    @builtins.property
    def aggregation_rule(self) -> typing.Optional[AggregationRule]:
        '''AggregationRule is an optional field that describes how to build the Rules for this ClusterRole.

        If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be stomped by the controller.

        :schema: io.k8s.api.rbac.v1.ClusterRole#aggregationRule
        '''
        result = self._values.get("aggregation_rule")
        return typing.cast(typing.Optional[AggregationRule], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.ClusterRole#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List["PolicyRule"]]:
        '''Rules holds all the PolicyRules for this ClusterRole.

        :schema: io.k8s.api.rbac.v1.ClusterRole#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List["PolicyRule"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeClusterRoleProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeComponentStatus(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeComponentStatus",
):
    '''ComponentStatus (and ComponentStatusList) holds the cluster validation info.

    Deprecated: This API is deprecated in v1.19+

    :schema: io.k8s.api.core.v1.ComponentStatus
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        conditions: typing.Optional[typing.Sequence[typing.Union[ComponentCondition, typing.Dict[str, typing.Any]]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ComponentStatus" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param conditions: List of component conditions observed.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                conditions: typing.Optional[typing.Sequence[typing.Union[ComponentCondition, typing.Dict[str, typing.Any]]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeComponentStatusProps(conditions=conditions, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        conditions: typing.Optional[typing.Sequence[typing.Union[ComponentCondition, typing.Dict[str, typing.Any]]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ComponentStatus".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param conditions: List of component conditions observed.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeComponentStatusProps(conditions=conditions, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ComponentStatus".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeComponentStatusList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeComponentStatusList",
):
    '''Status of all the conditions for the component as a list of ComponentStatus objects.

    Deprecated: This API is deprecated in v1.19+

    :schema: io.k8s.api.core.v1.ComponentStatusList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeComponentStatusProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ComponentStatusList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of ComponentStatus objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeComponentStatusProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeComponentStatusListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeComponentStatusProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ComponentStatusList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of ComponentStatus objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeComponentStatusListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ComponentStatusList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeComponentStatusListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeComponentStatusListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeComponentStatusProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Status of all the conditions for the component as a list of ComponentStatus objects.

        Deprecated: This API is deprecated in v1.19+

        :param items: List of ComponentStatus objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ComponentStatusList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeComponentStatusProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeComponentStatusProps"]:
        '''List of ComponentStatus objects.

        :schema: io.k8s.api.core.v1.ComponentStatusList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeComponentStatusProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ComponentStatusList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeComponentStatusListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeComponentStatusProps",
    jsii_struct_bases=[],
    name_mapping={"conditions": "conditions", "metadata": "metadata"},
)
class KubeComponentStatusProps:
    def __init__(
        self,
        *,
        conditions: typing.Optional[typing.Sequence[typing.Union[ComponentCondition, typing.Dict[str, typing.Any]]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ComponentStatus (and ComponentStatusList) holds the cluster validation info.

        Deprecated: This API is deprecated in v1.19+

        :param conditions: List of component conditions observed.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ComponentStatus
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                conditions: typing.Optional[typing.Sequence[typing.Union[ComponentCondition, typing.Dict[str, typing.Any]]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument conditions", value=conditions, expected_type=type_hints["conditions"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {}
        if conditions is not None:
            self._values["conditions"] = conditions
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def conditions(self) -> typing.Optional[typing.List[ComponentCondition]]:
        '''List of component conditions observed.

        :schema: io.k8s.api.core.v1.ComponentStatus#conditions
        '''
        result = self._values.get("conditions")
        return typing.cast(typing.Optional[typing.List[ComponentCondition]], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ComponentStatus#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeComponentStatusProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeConfigMap(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeConfigMap",
):
    '''ConfigMap holds configuration data for pods to consume.

    :schema: io.k8s.api.core.v1.ConfigMap
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        binary_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        immutable: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ConfigMap" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param binary_data: BinaryData contains the binary data. Each key must consist of alphanumeric characters, '-', '_' or '.'. BinaryData can contain byte sequences that are not in the UTF-8 range. The keys stored in BinaryData must not overlap with the ones in the Data field, this is enforced during validation process. Using this field will require 1.10+ apiserver and kubelet.
        :param data: Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.
        :param immutable: Immutable, if set to true, ensures that data stored in the ConfigMap cannot be updated (only object metadata can be modified). If not set to true, the field can be modified at any time. Defaulted to nil.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                binary_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                immutable: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeConfigMapProps(
            binary_data=binary_data, data=data, immutable=immutable, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        binary_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        immutable: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ConfigMap".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param binary_data: BinaryData contains the binary data. Each key must consist of alphanumeric characters, '-', '_' or '.'. BinaryData can contain byte sequences that are not in the UTF-8 range. The keys stored in BinaryData must not overlap with the ones in the Data field, this is enforced during validation process. Using this field will require 1.10+ apiserver and kubelet.
        :param data: Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.
        :param immutable: Immutable, if set to true, ensures that data stored in the ConfigMap cannot be updated (only object metadata can be modified). If not set to true, the field can be modified at any time. Defaulted to nil.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeConfigMapProps(
            binary_data=binary_data, data=data, immutable=immutable, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ConfigMap".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeConfigMapList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeConfigMapList",
):
    '''ConfigMapList is a resource containing a list of ConfigMap objects.

    :schema: io.k8s.api.core.v1.ConfigMapList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeConfigMapProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ConfigMapList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of ConfigMaps.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeConfigMapProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeConfigMapListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeConfigMapProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ConfigMapList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of ConfigMaps.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeConfigMapListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ConfigMapList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeConfigMapListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeConfigMapListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeConfigMapProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ConfigMapList is a resource containing a list of ConfigMap objects.

        :param items: Items is the list of ConfigMaps.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.core.v1.ConfigMapList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeConfigMapProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeConfigMapProps"]:
        '''Items is the list of ConfigMaps.

        :schema: io.k8s.api.core.v1.ConfigMapList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeConfigMapProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.core.v1.ConfigMapList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeConfigMapListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeConfigMapProps",
    jsii_struct_bases=[],
    name_mapping={
        "binary_data": "binaryData",
        "data": "data",
        "immutable": "immutable",
        "metadata": "metadata",
    },
)
class KubeConfigMapProps:
    def __init__(
        self,
        *,
        binary_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        immutable: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ConfigMap holds configuration data for pods to consume.

        :param binary_data: BinaryData contains the binary data. Each key must consist of alphanumeric characters, '-', '_' or '.'. BinaryData can contain byte sequences that are not in the UTF-8 range. The keys stored in BinaryData must not overlap with the ones in the Data field, this is enforced during validation process. Using this field will require 1.10+ apiserver and kubelet.
        :param data: Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.
        :param immutable: Immutable, if set to true, ensures that data stored in the ConfigMap cannot be updated (only object metadata can be modified). If not set to true, the field can be modified at any time. Defaulted to nil.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ConfigMap
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                binary_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                immutable: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument binary_data", value=binary_data, expected_type=type_hints["binary_data"])
            check_type(argname="argument data", value=data, expected_type=type_hints["data"])
            check_type(argname="argument immutable", value=immutable, expected_type=type_hints["immutable"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {}
        if binary_data is not None:
            self._values["binary_data"] = binary_data
        if data is not None:
            self._values["data"] = data
        if immutable is not None:
            self._values["immutable"] = immutable
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def binary_data(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''BinaryData contains the binary data.

        Each key must consist of alphanumeric characters, '-', '_' or '.'. BinaryData can contain byte sequences that are not in the UTF-8 range. The keys stored in BinaryData must not overlap with the ones in the Data field, this is enforced during validation process. Using this field will require 1.10+ apiserver and kubelet.

        :schema: io.k8s.api.core.v1.ConfigMap#binaryData
        '''
        result = self._values.get("binary_data")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def data(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Data contains the configuration data.

        Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.

        :schema: io.k8s.api.core.v1.ConfigMap#data
        '''
        result = self._values.get("data")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def immutable(self) -> typing.Optional[builtins.bool]:
        '''Immutable, if set to true, ensures that data stored in the ConfigMap cannot be updated (only object metadata can be modified).

        If not set to true, the field can be modified at any time. Defaulted to nil.

        :schema: io.k8s.api.core.v1.ConfigMap#immutable
        '''
        result = self._values.get("immutable")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ConfigMap#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeConfigMapProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeControllerRevision(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeControllerRevision",
):
    '''ControllerRevision implements an immutable snapshot of state data.

    Clients are responsible for serializing and deserializing the objects that contain their internal state. Once a ControllerRevision has been successfully created, it can not be updated. The API Server will fail validation of all requests that attempt to mutate the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However, it may be subject to name and representation changes in future releases, and clients should not depend on its stability. It is primarily for internal use by controllers.

    :schema: io.k8s.api.apps.v1.ControllerRevision
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        revision: jsii.Number,
        data: typing.Any = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.ControllerRevision" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param revision: Revision indicates the revision of the state represented by Data.
        :param data: Data is the serialized representation of the state.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                revision: jsii.Number,
                data: typing.Any = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeControllerRevisionProps(
            revision=revision, data=data, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        revision: jsii.Number,
        data: typing.Any = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.ControllerRevision".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param revision: Revision indicates the revision of the state represented by Data.
        :param data: Data is the serialized representation of the state.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeControllerRevisionProps(
            revision=revision, data=data, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.ControllerRevision".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeControllerRevisionList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeControllerRevisionList",
):
    '''ControllerRevisionList is a resource containing a list of ControllerRevision objects.

    :schema: io.k8s.api.apps.v1.ControllerRevisionList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeControllerRevisionProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.ControllerRevisionList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of ControllerRevisions.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeControllerRevisionProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeControllerRevisionListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeControllerRevisionProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.ControllerRevisionList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of ControllerRevisions.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeControllerRevisionListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.ControllerRevisionList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeControllerRevisionListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeControllerRevisionListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeControllerRevisionProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ControllerRevisionList is a resource containing a list of ControllerRevision objects.

        :param items: Items is the list of ControllerRevisions.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.apps.v1.ControllerRevisionList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeControllerRevisionProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeControllerRevisionProps"]:
        '''Items is the list of ControllerRevisions.

        :schema: io.k8s.api.apps.v1.ControllerRevisionList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeControllerRevisionProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.apps.v1.ControllerRevisionList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeControllerRevisionListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeControllerRevisionProps",
    jsii_struct_bases=[],
    name_mapping={"revision": "revision", "data": "data", "metadata": "metadata"},
)
class KubeControllerRevisionProps:
    def __init__(
        self,
        *,
        revision: jsii.Number,
        data: typing.Any = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ControllerRevision implements an immutable snapshot of state data.

        Clients are responsible for serializing and deserializing the objects that contain their internal state. Once a ControllerRevision has been successfully created, it can not be updated. The API Server will fail validation of all requests that attempt to mutate the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However, it may be subject to name and representation changes in future releases, and clients should not depend on its stability. It is primarily for internal use by controllers.

        :param revision: Revision indicates the revision of the state represented by Data.
        :param data: Data is the serialized representation of the state.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.ControllerRevision
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                revision: jsii.Number,
                data: typing.Any = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument revision", value=revision, expected_type=type_hints["revision"])
            check_type(argname="argument data", value=data, expected_type=type_hints["data"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "revision": revision,
        }
        if data is not None:
            self._values["data"] = data
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def revision(self) -> jsii.Number:
        '''Revision indicates the revision of the state represented by Data.

        :schema: io.k8s.api.apps.v1.ControllerRevision#revision
        '''
        result = self._values.get("revision")
        assert result is not None, "Required property 'revision' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def data(self) -> typing.Any:
        '''Data is the serialized representation of the state.

        :schema: io.k8s.api.apps.v1.ControllerRevision#data
        '''
        result = self._values.get("data")
        return typing.cast(typing.Any, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.ControllerRevision#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeControllerRevisionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCronJob(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCronJob",
):
    '''CronJob represents the configuration of a single cron job.

    :schema: io.k8s.api.batch.v1.CronJob
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[CronJobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.batch.v1.CronJob" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a cron job, including the schedule. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[CronJobSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCronJobProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[CronJobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.batch.v1.CronJob".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a cron job, including the schedule. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeCronJobProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.batch.v1.CronJob".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeCronJobList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobList",
):
    '''CronJobList is a collection of cron jobs.

    :schema: io.k8s.api.batch.v1.CronJobList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCronJobProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.batch.v1.CronJobList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of CronJobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCronJobProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCronJobListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCronJobProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.batch.v1.CronJobList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of CronJobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeCronJobListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.batch.v1.CronJobList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCronJobListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCronJobProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CronJobList is a collection of cron jobs.

        :param items: items is the list of CronJobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.CronJobList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCronJobProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCronJobProps"]:
        '''items is the list of CronJobs.

        :schema: io.k8s.api.batch.v1.CronJobList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCronJobProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.CronJobList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCronJobListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCronJobListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobListV1Beta1",
):
    '''CronJobList is a collection of cron jobs.

    :schema: io.k8s.api.batch.v1beta1.CronJobList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCronJobV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.batch.v1beta1.CronJobList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of CronJobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCronJobV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCronJobListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCronJobV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.batch.v1beta1.CronJobList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of CronJobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeCronJobListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.batch.v1beta1.CronJobList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCronJobListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCronJobV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CronJobList is a collection of cron jobs.

        :param items: items is the list of CronJobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1beta1.CronJobList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCronJobV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCronJobV1Beta1Props"]:
        '''items is the list of CronJobs.

        :schema: io.k8s.api.batch.v1beta1.CronJobList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCronJobV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1beta1.CronJobList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCronJobListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeCronJobProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[CronJobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CronJob represents the configuration of a single cron job.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a cron job, including the schedule. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1.CronJob
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = CronJobSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[CronJobSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.CronJob#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[CronJobSpec]:
        '''Specification of the desired behavior of a cron job, including the schedule.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1.CronJob#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[CronJobSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCronJobProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCronJobV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobV1Beta1",
):
    '''CronJob represents the configuration of a single cron job.

    :schema: io.k8s.api.batch.v1beta1.CronJob
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[CronJobSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.batch.v1beta1.CronJob" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a cron job, including the schedule. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[CronJobSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCronJobV1Beta1Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[CronJobSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.batch.v1beta1.CronJob".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a cron job, including the schedule. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeCronJobV1Beta1Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.batch.v1beta1.CronJob".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCronJobV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeCronJobV1Beta1Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[CronJobSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CronJob represents the configuration of a single cron job.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a cron job, including the schedule. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1beta1.CronJob
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = CronJobSpecV1Beta1(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[CronJobSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1beta1.CronJob#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[CronJobSpecV1Beta1]:
        '''Specification of the desired behavior of a cron job, including the schedule.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1beta1.CronJob#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[CronJobSpecV1Beta1], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCronJobV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCsiDriver(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiDriver",
):
    '''CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster.

    Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.

    :schema: io.k8s.api.storage.v1.CSIDriver
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union[CsiDriverSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.CSIDriver" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Specification of the CSI Driver.
        :param metadata: Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[CsiDriverSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiDriverProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union[CsiDriverSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.CSIDriver".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Specification of the CSI Driver.
        :param metadata: Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeCsiDriverProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.CSIDriver".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeCsiDriverList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiDriverList",
):
    '''CSIDriverList is a collection of CSIDriver objects.

    :schema: io.k8s.api.storage.v1.CSIDriverList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCsiDriverProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.CSIDriverList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of CSIDriver.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCsiDriverProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiDriverListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCsiDriverProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.CSIDriverList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of CSIDriver.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeCsiDriverListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.CSIDriverList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiDriverListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCsiDriverListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCsiDriverProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSIDriverList is a collection of CSIDriver objects.

        :param items: items is the list of CSIDriver.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.CSIDriverList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCsiDriverProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCsiDriverProps"]:
        '''items is the list of CSIDriver.

        :schema: io.k8s.api.storage.v1.CSIDriverList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCsiDriverProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.CSIDriverList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiDriverListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiDriverProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeCsiDriverProps:
    def __init__(
        self,
        *,
        spec: typing.Union[CsiDriverSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster.

        Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.

        :param spec: Specification of the CSI Driver.
        :param metadata: Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1.CSIDriver
        '''
        if isinstance(spec, dict):
            spec = CsiDriverSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[CsiDriverSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> CsiDriverSpec:
        '''Specification of the CSI Driver.

        :schema: io.k8s.api.storage.v1.CSIDriver#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(CsiDriverSpec, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object metadata.

        metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1.CSIDriver#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiDriverProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCsiNode(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiNode",
):
    '''CSINode holds information about all CSI drivers installed on a node.

    CSI drivers do not need to create the CSINode object directly. As long as they use the node-driver-registrar sidecar container, the kubelet will automatically populate the CSINode object for the CSI driver as part of kubelet plugin registration. CSINode has the same name as a node. If the object is missing, it means either there are no CSI Drivers available on the node, or the Kubelet version is low enough that it doesn't create this object. CSINode has an OwnerReference that points to the corresponding node object.

    :schema: io.k8s.api.storage.v1.CSINode
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union[CsiNodeSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.CSINode" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: spec is the specification of CSINode.
        :param metadata: metadata.name must be the Kubernetes node name.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[CsiNodeSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiNodeProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union[CsiNodeSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.CSINode".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: spec is the specification of CSINode.
        :param metadata: metadata.name must be the Kubernetes node name.
        '''
        props = KubeCsiNodeProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.CSINode".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeCsiNodeList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiNodeList",
):
    '''CSINodeList is a collection of CSINode objects.

    :schema: io.k8s.api.storage.v1.CSINodeList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCsiNodeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.CSINodeList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of CSINode.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCsiNodeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiNodeListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCsiNodeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.CSINodeList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of CSINode.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeCsiNodeListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.CSINodeList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiNodeListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCsiNodeListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCsiNodeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSINodeList is a collection of CSINode objects.

        :param items: items is the list of CSINode.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.CSINodeList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCsiNodeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCsiNodeProps"]:
        '''items is the list of CSINode.

        :schema: io.k8s.api.storage.v1.CSINodeList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCsiNodeProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.CSINodeList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiNodeListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiNodeProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeCsiNodeProps:
    def __init__(
        self,
        *,
        spec: typing.Union[CsiNodeSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSINode holds information about all CSI drivers installed on a node.

        CSI drivers do not need to create the CSINode object directly. As long as they use the node-driver-registrar sidecar container, the kubelet will automatically populate the CSINode object for the CSI driver as part of kubelet plugin registration. CSINode has the same name as a node. If the object is missing, it means either there are no CSI Drivers available on the node, or the Kubelet version is low enough that it doesn't create this object. CSINode has an OwnerReference that points to the corresponding node object.

        :param spec: spec is the specification of CSINode.
        :param metadata: metadata.name must be the Kubernetes node name.

        :schema: io.k8s.api.storage.v1.CSINode
        '''
        if isinstance(spec, dict):
            spec = CsiNodeSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[CsiNodeSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> CsiNodeSpec:
        '''spec is the specification of CSINode.

        :schema: io.k8s.api.storage.v1.CSINode#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(CsiNodeSpec, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''metadata.name must be the Kubernetes node name.

        :schema: io.k8s.api.storage.v1.CSINode#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiNodeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCsiStorageCapacityListV1Alpha1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityListV1Alpha1",
):
    '''CSIStorageCapacityList is a collection of CSIStorageCapacity objects.

    :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacityList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCsiStorageCapacityV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1alpha1.CSIStorageCapacityList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of CSIStorageCapacity objects.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCsiStorageCapacityV1Alpha1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiStorageCapacityListV1Alpha1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCsiStorageCapacityV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1alpha1.CSIStorageCapacityList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of CSIStorageCapacity objects.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeCsiStorageCapacityListV1Alpha1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1alpha1.CSIStorageCapacityList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityListV1Alpha1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCsiStorageCapacityListV1Alpha1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCsiStorageCapacityV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSIStorageCapacityList is a collection of CSIStorageCapacity objects.

        :param items: Items is the list of CSIStorageCapacity objects.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacityList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCsiStorageCapacityV1Alpha1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCsiStorageCapacityV1Alpha1Props"]:
        '''Items is the list of CSIStorageCapacity objects.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacityList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCsiStorageCapacityV1Alpha1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacityList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiStorageCapacityListV1Alpha1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCsiStorageCapacityListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityListV1Beta1",
):
    '''CSIStorageCapacityList is a collection of CSIStorageCapacity objects.

    :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacityList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCsiStorageCapacityV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1beta1.CSIStorageCapacityList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of CSIStorageCapacity objects.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCsiStorageCapacityV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiStorageCapacityListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCsiStorageCapacityV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1beta1.CSIStorageCapacityList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of CSIStorageCapacity objects.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeCsiStorageCapacityListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1beta1.CSIStorageCapacityList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCsiStorageCapacityListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCsiStorageCapacityV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSIStorageCapacityList is a collection of CSIStorageCapacity objects.

        :param items: Items is the list of CSIStorageCapacity objects.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacityList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCsiStorageCapacityV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCsiStorageCapacityV1Beta1Props"]:
        '''Items is the list of CSIStorageCapacity objects.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacityList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCsiStorageCapacityV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacityList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiStorageCapacityListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCsiStorageCapacityV1Alpha1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityV1Alpha1",
):
    '''CSIStorageCapacity stores the result of one CSI GetCapacity call.

    For a given StorageClass, this describes the available capacity in a particular topology segment.  This can be used when considering where to instantiate new PersistentVolumes.

    For example this can express things like: - StorageClass "standard" has "1234 GiB" available in "topology.kubernetes.io/zone=us-east1" - StorageClass "localssd" has "10 GiB" available in "kubernetes.io/hostname=knode-abc123"

    The following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero

    The producer of these objects can decide which approach is more suitable.

    They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.

    :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        storage_class_name: builtins.str,
        capacity: typing.Optional["Quantity"] = None,
        maximum_volume_size: typing.Optional["Quantity"] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        node_topology: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1alpha1.CSIStorageCapacity" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param storage_class_name: The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.
        :param capacity: Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.
        :param maximum_volume_size: MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.
        :param metadata: Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name. Objects are namespaced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param node_topology: NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                storage_class_name: builtins.str,
                capacity: typing.Optional[Quantity] = None,
                maximum_volume_size: typing.Optional[Quantity] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                node_topology: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiStorageCapacityV1Alpha1Props(
            storage_class_name=storage_class_name,
            capacity=capacity,
            maximum_volume_size=maximum_volume_size,
            metadata=metadata,
            node_topology=node_topology,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        storage_class_name: builtins.str,
        capacity: typing.Optional["Quantity"] = None,
        maximum_volume_size: typing.Optional["Quantity"] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        node_topology: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1alpha1.CSIStorageCapacity".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param storage_class_name: The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.
        :param capacity: Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.
        :param maximum_volume_size: MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.
        :param metadata: Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name. Objects are namespaced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param node_topology: NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.
        '''
        props = KubeCsiStorageCapacityV1Alpha1Props(
            storage_class_name=storage_class_name,
            capacity=capacity,
            maximum_volume_size=maximum_volume_size,
            metadata=metadata,
            node_topology=node_topology,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1alpha1.CSIStorageCapacity".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityV1Alpha1Props",
    jsii_struct_bases=[],
    name_mapping={
        "storage_class_name": "storageClassName",
        "capacity": "capacity",
        "maximum_volume_size": "maximumVolumeSize",
        "metadata": "metadata",
        "node_topology": "nodeTopology",
    },
)
class KubeCsiStorageCapacityV1Alpha1Props:
    def __init__(
        self,
        *,
        storage_class_name: builtins.str,
        capacity: typing.Optional["Quantity"] = None,
        maximum_volume_size: typing.Optional["Quantity"] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        node_topology: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSIStorageCapacity stores the result of one CSI GetCapacity call.

        For a given StorageClass, this describes the available capacity in a particular topology segment.  This can be used when considering where to instantiate new PersistentVolumes.

        For example this can express things like: - StorageClass "standard" has "1234 GiB" available in "topology.kubernetes.io/zone=us-east1" - StorageClass "localssd" has "10 GiB" available in "kubernetes.io/hostname=knode-abc123"

        The following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero

        The producer of these objects can decide which approach is more suitable.

        They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.

        :param storage_class_name: The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.
        :param capacity: Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.
        :param maximum_volume_size: MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.
        :param metadata: Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name. Objects are namespaced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param node_topology: NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(node_topology, dict):
            node_topology = LabelSelector(**node_topology)
        if __debug__:
            def stub(
                *,
                storage_class_name: builtins.str,
                capacity: typing.Optional[Quantity] = None,
                maximum_volume_size: typing.Optional[Quantity] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                node_topology: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument storage_class_name", value=storage_class_name, expected_type=type_hints["storage_class_name"])
            check_type(argname="argument capacity", value=capacity, expected_type=type_hints["capacity"])
            check_type(argname="argument maximum_volume_size", value=maximum_volume_size, expected_type=type_hints["maximum_volume_size"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument node_topology", value=node_topology, expected_type=type_hints["node_topology"])
        self._values: typing.Dict[str, typing.Any] = {
            "storage_class_name": storage_class_name,
        }
        if capacity is not None:
            self._values["capacity"] = capacity
        if maximum_volume_size is not None:
            self._values["maximum_volume_size"] = maximum_volume_size
        if metadata is not None:
            self._values["metadata"] = metadata
        if node_topology is not None:
            self._values["node_topology"] = node_topology

    @builtins.property
    def storage_class_name(self) -> builtins.str:
        '''The name of the StorageClass that the reported capacity applies to.

        It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity#storageClassName
        '''
        result = self._values.get("storage_class_name")
        assert result is not None, "Required property 'storage_class_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def capacity(self) -> typing.Optional["Quantity"]:
        '''Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.

        The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity#capacity
        '''
        result = self._values.get("capacity")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def maximum_volume_size(self) -> typing.Optional["Quantity"]:
        '''MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.

        This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity#maximumVolumeSize
        '''
        result = self._values.get("maximum_volume_size")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.

        Objects are namespaced.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def node_topology(self) -> typing.Optional["LabelSelector"]:
        '''NodeTopology defines which nodes have access to the storage for which capacity was reported.

        If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.

        :schema: io.k8s.api.storage.v1alpha1.CSIStorageCapacity#nodeTopology
        '''
        result = self._values.get("node_topology")
        return typing.cast(typing.Optional["LabelSelector"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiStorageCapacityV1Alpha1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCsiStorageCapacityV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityV1Beta1",
):
    '''CSIStorageCapacity stores the result of one CSI GetCapacity call.

    For a given StorageClass, this describes the available capacity in a particular topology segment.  This can be used when considering where to instantiate new PersistentVolumes.

    For example this can express things like: - StorageClass "standard" has "1234 GiB" available in "topology.kubernetes.io/zone=us-east1" - StorageClass "localssd" has "10 GiB" available in "kubernetes.io/hostname=knode-abc123"

    The following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero

    The producer of these objects can decide which approach is more suitable.

    They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.

    :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        storage_class_name: builtins.str,
        capacity: typing.Optional["Quantity"] = None,
        maximum_volume_size: typing.Optional["Quantity"] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        node_topology: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1beta1.CSIStorageCapacity" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param storage_class_name: The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.
        :param capacity: Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.
        :param maximum_volume_size: MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.
        :param metadata: Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name. Objects are namespaced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param node_topology: NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                storage_class_name: builtins.str,
                capacity: typing.Optional[Quantity] = None,
                maximum_volume_size: typing.Optional[Quantity] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                node_topology: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCsiStorageCapacityV1Beta1Props(
            storage_class_name=storage_class_name,
            capacity=capacity,
            maximum_volume_size=maximum_volume_size,
            metadata=metadata,
            node_topology=node_topology,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        storage_class_name: builtins.str,
        capacity: typing.Optional["Quantity"] = None,
        maximum_volume_size: typing.Optional["Quantity"] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        node_topology: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1beta1.CSIStorageCapacity".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param storage_class_name: The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.
        :param capacity: Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.
        :param maximum_volume_size: MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.
        :param metadata: Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name. Objects are namespaced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param node_topology: NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.
        '''
        props = KubeCsiStorageCapacityV1Beta1Props(
            storage_class_name=storage_class_name,
            capacity=capacity,
            maximum_volume_size=maximum_volume_size,
            metadata=metadata,
            node_topology=node_topology,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1beta1.CSIStorageCapacity".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCsiStorageCapacityV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={
        "storage_class_name": "storageClassName",
        "capacity": "capacity",
        "maximum_volume_size": "maximumVolumeSize",
        "metadata": "metadata",
        "node_topology": "nodeTopology",
    },
)
class KubeCsiStorageCapacityV1Beta1Props:
    def __init__(
        self,
        *,
        storage_class_name: builtins.str,
        capacity: typing.Optional["Quantity"] = None,
        maximum_volume_size: typing.Optional["Quantity"] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        node_topology: typing.Optional[typing.Union["LabelSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CSIStorageCapacity stores the result of one CSI GetCapacity call.

        For a given StorageClass, this describes the available capacity in a particular topology segment.  This can be used when considering where to instantiate new PersistentVolumes.

        For example this can express things like: - StorageClass "standard" has "1234 GiB" available in "topology.kubernetes.io/zone=us-east1" - StorageClass "localssd" has "10 GiB" available in "kubernetes.io/hostname=knode-abc123"

        The following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero

        The producer of these objects can decide which approach is more suitable.

        They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.

        :param storage_class_name: The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.
        :param capacity: Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.
        :param maximum_volume_size: MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields. This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.
        :param metadata: Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name. Objects are namespaced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param node_topology: NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(node_topology, dict):
            node_topology = LabelSelector(**node_topology)
        if __debug__:
            def stub(
                *,
                storage_class_name: builtins.str,
                capacity: typing.Optional[Quantity] = None,
                maximum_volume_size: typing.Optional[Quantity] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                node_topology: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument storage_class_name", value=storage_class_name, expected_type=type_hints["storage_class_name"])
            check_type(argname="argument capacity", value=capacity, expected_type=type_hints["capacity"])
            check_type(argname="argument maximum_volume_size", value=maximum_volume_size, expected_type=type_hints["maximum_volume_size"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument node_topology", value=node_topology, expected_type=type_hints["node_topology"])
        self._values: typing.Dict[str, typing.Any] = {
            "storage_class_name": storage_class_name,
        }
        if capacity is not None:
            self._values["capacity"] = capacity
        if maximum_volume_size is not None:
            self._values["maximum_volume_size"] = maximum_volume_size
        if metadata is not None:
            self._values["metadata"] = metadata
        if node_topology is not None:
            self._values["node_topology"] = node_topology

    @builtins.property
    def storage_class_name(self) -> builtins.str:
        '''The name of the StorageClass that the reported capacity applies to.

        It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity#storageClassName
        '''
        result = self._values.get("storage_class_name")
        assert result is not None, "Required property 'storage_class_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def capacity(self) -> typing.Optional["Quantity"]:
        '''Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.

        The semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity#capacity
        '''
        result = self._values.get("capacity")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def maximum_volume_size(self) -> typing.Optional["Quantity"]:
        '''MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.

        This is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity#maximumVolumeSize
        '''
        result = self._values.get("maximum_volume_size")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.

        Objects are namespaced.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def node_topology(self) -> typing.Optional["LabelSelector"]:
        '''NodeTopology defines which nodes have access to the storage for which capacity was reported.

        If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.

        :schema: io.k8s.api.storage.v1beta1.CSIStorageCapacity#nodeTopology
        '''
        result = self._values.get("node_topology")
        return typing.cast(typing.Optional["LabelSelector"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCsiStorageCapacityV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeCustomResourceDefinition(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCustomResourceDefinition",
):
    '''CustomResourceDefinition represents a resource that should be exposed on the API server.

    Its name MUST be in the format <.spec.name>.<.spec.group>.

    :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union[CustomResourceDefinitionSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: spec describes how the user wants the resources to appear.
        :param metadata: Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[CustomResourceDefinitionSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCustomResourceDefinitionProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union[CustomResourceDefinitionSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: spec describes how the user wants the resources to appear.
        :param metadata: Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeCustomResourceDefinitionProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeCustomResourceDefinitionList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeCustomResourceDefinitionList",
):
    '''CustomResourceDefinitionList is a list of CustomResourceDefinition objects.

    :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeCustomResourceDefinitionProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items list individual CustomResourceDefinition objects.
        :param metadata: Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeCustomResourceDefinitionProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeCustomResourceDefinitionListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeCustomResourceDefinitionProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items list individual CustomResourceDefinition objects.
        :param metadata: Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeCustomResourceDefinitionListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCustomResourceDefinitionListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeCustomResourceDefinitionListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeCustomResourceDefinitionProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CustomResourceDefinitionList is a list of CustomResourceDefinition objects.

        :param items: items list individual CustomResourceDefinition objects.
        :param metadata: Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeCustomResourceDefinitionProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeCustomResourceDefinitionProps"]:
        '''items list individual CustomResourceDefinition objects.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeCustomResourceDefinitionProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinitionList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCustomResourceDefinitionListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeCustomResourceDefinitionProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeCustomResourceDefinitionProps:
    def __init__(
        self,
        *,
        spec: typing.Union[CustomResourceDefinitionSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''CustomResourceDefinition represents a resource that should be exposed on the API server.

        Its name MUST be in the format <.spec.name>.<.spec.group>.

        :param spec: spec describes how the user wants the resources to appear.
        :param metadata: Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition
        '''
        if isinstance(spec, dict):
            spec = CustomResourceDefinitionSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[CustomResourceDefinitionSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> CustomResourceDefinitionSpec:
        '''spec describes how the user wants the resources to appear.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(CustomResourceDefinitionSpec, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeCustomResourceDefinitionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeDaemonSet(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeDaemonSet",
):
    '''DaemonSet represents the configuration of a daemon set.

    :schema: io.k8s.api.apps.v1.DaemonSet
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[DaemonSetSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.DaemonSet" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: The desired behavior of this daemon set. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[DaemonSetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeDaemonSetProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[DaemonSetSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.DaemonSet".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: The desired behavior of this daemon set. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeDaemonSetProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.DaemonSet".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeDaemonSetList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeDaemonSetList",
):
    '''DaemonSetList is a collection of daemon sets.

    :schema: io.k8s.api.apps.v1.DaemonSetList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeDaemonSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.DaemonSetList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: A list of daemon sets.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeDaemonSetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeDaemonSetListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeDaemonSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.DaemonSetList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: A list of daemon sets.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeDaemonSetListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.DaemonSetList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeDaemonSetListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeDaemonSetListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeDaemonSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''DaemonSetList is a collection of daemon sets.

        :param items: A list of daemon sets.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.DaemonSetList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeDaemonSetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeDaemonSetProps"]:
        '''A list of daemon sets.

        :schema: io.k8s.api.apps.v1.DaemonSetList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeDaemonSetProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.DaemonSetList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeDaemonSetListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeDaemonSetProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeDaemonSetProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[DaemonSetSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''DaemonSet represents the configuration of a daemon set.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: The desired behavior of this daemon set. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.apps.v1.DaemonSet
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = DaemonSetSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[DaemonSetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.DaemonSet#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[DaemonSetSpec]:
        '''The desired behavior of this daemon set.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.apps.v1.DaemonSet#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[DaemonSetSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeDaemonSetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeDeployment(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeDeployment",
):
    '''Deployment enables declarative updates for Pods and ReplicaSets.

    :schema: io.k8s.api.apps.v1.Deployment
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[DeploymentSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.Deployment" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the Deployment.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[DeploymentSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeDeploymentProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[DeploymentSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.Deployment".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the Deployment.
        '''
        props = KubeDeploymentProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.Deployment".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeDeploymentList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeDeploymentList",
):
    '''DeploymentList is a list of Deployments.

    :schema: io.k8s.api.apps.v1.DeploymentList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeDeploymentProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.DeploymentList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of Deployments.
        :param metadata: Standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeDeploymentProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeDeploymentListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeDeploymentProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.DeploymentList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of Deployments.
        :param metadata: Standard list metadata.
        '''
        props = KubeDeploymentListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.DeploymentList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeDeploymentListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeDeploymentListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeDeploymentProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''DeploymentList is a list of Deployments.

        :param items: Items is the list of Deployments.
        :param metadata: Standard list metadata.

        :schema: io.k8s.api.apps.v1.DeploymentList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeDeploymentProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeDeploymentProps"]:
        '''Items is the list of Deployments.

        :schema: io.k8s.api.apps.v1.DeploymentList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeDeploymentProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        :schema: io.k8s.api.apps.v1.DeploymentList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeDeploymentListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeDeploymentProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeDeploymentProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[DeploymentSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Deployment enables declarative updates for Pods and ReplicaSets.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the Deployment.

        :schema: io.k8s.api.apps.v1.Deployment
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = DeploymentSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[DeploymentSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.Deployment#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[DeploymentSpec]:
        '''Specification of the desired behavior of the Deployment.

        :schema: io.k8s.api.apps.v1.Deployment#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[DeploymentSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeDeploymentProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEndpointSlice(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSlice",
):
    '''EndpointSlice represents a subset of the endpoints that implement a service.

    For a given service there may be multiple EndpointSlice objects, selected by labels, which must be joined to produce the full set of endpoints.

    :schema: io.k8s.api.discovery.v1.EndpointSlice
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        address_type: IoK8SApiDiscoveryV1EndpointSliceAddressType,
        endpoints: typing.Sequence[typing.Union[Endpoint, typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.discovery.v1.EndpointSlice" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param address_type: addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name. Possible enum values: - ``"FQDN"`` represents a FQDN. - ``"IPv4"`` represents an IPv4 Address. - ``"IPv6"`` represents an IPv6 Address.
        :param endpoints: endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.
        :param metadata: Standard object's metadata.
        :param ports: ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                address_type: IoK8SApiDiscoveryV1EndpointSliceAddressType,
                endpoints: typing.Sequence[typing.Union[Endpoint, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEndpointSliceProps(
            address_type=address_type,
            endpoints=endpoints,
            metadata=metadata,
            ports=ports,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        address_type: IoK8SApiDiscoveryV1EndpointSliceAddressType,
        endpoints: typing.Sequence[typing.Union[Endpoint, typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.discovery.v1.EndpointSlice".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param address_type: addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name. Possible enum values: - ``"FQDN"`` represents a FQDN. - ``"IPv4"`` represents an IPv4 Address. - ``"IPv6"`` represents an IPv6 Address.
        :param endpoints: endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.
        :param metadata: Standard object's metadata.
        :param ports: ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.
        '''
        props = KubeEndpointSliceProps(
            address_type=address_type,
            endpoints=endpoints,
            metadata=metadata,
            ports=ports,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.discovery.v1.EndpointSlice".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeEndpointSliceList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceList",
):
    '''EndpointSliceList represents a list of endpoint slices.

    :schema: io.k8s.api.discovery.v1.EndpointSliceList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointSliceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.discovery.v1.EndpointSliceList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of endpoint slices.
        :param metadata: Standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeEndpointSliceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEndpointSliceListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointSliceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.discovery.v1.EndpointSliceList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of endpoint slices.
        :param metadata: Standard list metadata.
        '''
        props = KubeEndpointSliceListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.discovery.v1.EndpointSliceList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeEndpointSliceListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointSliceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EndpointSliceList represents a list of endpoint slices.

        :param items: List of endpoint slices.
        :param metadata: Standard list metadata.

        :schema: io.k8s.api.discovery.v1.EndpointSliceList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeEndpointSliceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeEndpointSliceProps"]:
        '''List of endpoint slices.

        :schema: io.k8s.api.discovery.v1.EndpointSliceList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeEndpointSliceProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        :schema: io.k8s.api.discovery.v1.EndpointSliceList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEndpointSliceListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEndpointSliceListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceListV1Beta1",
):
    '''EndpointSliceList represents a list of endpoint slices.

    :schema: io.k8s.api.discovery.v1beta1.EndpointSliceList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointSliceV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.discovery.v1beta1.EndpointSliceList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of endpoint slices.
        :param metadata: Standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeEndpointSliceV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEndpointSliceListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointSliceV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.discovery.v1beta1.EndpointSliceList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of endpoint slices.
        :param metadata: Standard list metadata.
        '''
        props = KubeEndpointSliceListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.discovery.v1beta1.EndpointSliceList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeEndpointSliceListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointSliceV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EndpointSliceList represents a list of endpoint slices.

        :param items: List of endpoint slices.
        :param metadata: Standard list metadata.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSliceList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeEndpointSliceV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeEndpointSliceV1Beta1Props"]:
        '''List of endpoint slices.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSliceList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeEndpointSliceV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSliceList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEndpointSliceListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceProps",
    jsii_struct_bases=[],
    name_mapping={
        "address_type": "addressType",
        "endpoints": "endpoints",
        "metadata": "metadata",
        "ports": "ports",
    },
)
class KubeEndpointSliceProps:
    def __init__(
        self,
        *,
        address_type: IoK8SApiDiscoveryV1EndpointSliceAddressType,
        endpoints: typing.Sequence[typing.Union[Endpoint, typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''EndpointSlice represents a subset of the endpoints that implement a service.

        For a given service there may be multiple EndpointSlice objects, selected by labels, which must be joined to produce the full set of endpoints.

        :param address_type: addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name. Possible enum values: - ``"FQDN"`` represents a FQDN. - ``"IPv4"`` represents an IPv4 Address. - ``"IPv6"`` represents an IPv6 Address.
        :param endpoints: endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.
        :param metadata: Standard object's metadata.
        :param ports: ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.

        :schema: io.k8s.api.discovery.v1.EndpointSlice
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                address_type: IoK8SApiDiscoveryV1EndpointSliceAddressType,
                endpoints: typing.Sequence[typing.Union[Endpoint, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[EndpointPort, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument address_type", value=address_type, expected_type=type_hints["address_type"])
            check_type(argname="argument endpoints", value=endpoints, expected_type=type_hints["endpoints"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
        self._values: typing.Dict[str, typing.Any] = {
            "address_type": address_type,
            "endpoints": endpoints,
        }
        if metadata is not None:
            self._values["metadata"] = metadata
        if ports is not None:
            self._values["ports"] = ports

    @builtins.property
    def address_type(self) -> IoK8SApiDiscoveryV1EndpointSliceAddressType:
        '''addressType specifies the type of address carried by this EndpointSlice.

        All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.

        Possible enum values:

        - ``"FQDN"`` represents a FQDN.
        - ``"IPv4"`` represents an IPv4 Address.
        - ``"IPv6"`` represents an IPv6 Address.

        :schema: io.k8s.api.discovery.v1.EndpointSlice#addressType
        '''
        result = self._values.get("address_type")
        assert result is not None, "Required property 'address_type' is missing"
        return typing.cast(IoK8SApiDiscoveryV1EndpointSliceAddressType, result)

    @builtins.property
    def endpoints(self) -> typing.List[Endpoint]:
        '''endpoints is a list of unique endpoints in this slice.

        Each slice may include a maximum of 1000 endpoints.

        :schema: io.k8s.api.discovery.v1.EndpointSlice#endpoints
        '''
        result = self._values.get("endpoints")
        assert result is not None, "Required property 'endpoints' is missing"
        return typing.cast(typing.List[Endpoint], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.discovery.v1.EndpointSlice#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List[EndpointPort]]:
        '''ports specifies the list of network ports exposed by each endpoint in this slice.

        Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.

        :schema: io.k8s.api.discovery.v1.EndpointSlice#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List[EndpointPort]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEndpointSliceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEndpointSliceV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceV1Beta1",
):
    '''EndpointSlice represents a subset of the endpoints that implement a service.

    For a given service there may be multiple EndpointSlice objects, selected by labels, which must be joined to produce the full set of endpoints.

    :schema: io.k8s.api.discovery.v1beta1.EndpointSlice
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        address_type: builtins.str,
        endpoints: typing.Sequence[typing.Union[EndpointV1Beta1, typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPortV1Beta1, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.discovery.v1beta1.EndpointSlice" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param address_type: addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.
        :param endpoints: endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.
        :param metadata: Standard object's metadata.
        :param ports: ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                address_type: builtins.str,
                endpoints: typing.Sequence[typing.Union[EndpointV1Beta1, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[EndpointPortV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEndpointSliceV1Beta1Props(
            address_type=address_type,
            endpoints=endpoints,
            metadata=metadata,
            ports=ports,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        address_type: builtins.str,
        endpoints: typing.Sequence[typing.Union[EndpointV1Beta1, typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPortV1Beta1, typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.discovery.v1beta1.EndpointSlice".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param address_type: addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.
        :param endpoints: endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.
        :param metadata: Standard object's metadata.
        :param ports: ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.
        '''
        props = KubeEndpointSliceV1Beta1Props(
            address_type=address_type,
            endpoints=endpoints,
            metadata=metadata,
            ports=ports,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.discovery.v1beta1.EndpointSlice".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointSliceV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={
        "address_type": "addressType",
        "endpoints": "endpoints",
        "metadata": "metadata",
        "ports": "ports",
    },
)
class KubeEndpointSliceV1Beta1Props:
    def __init__(
        self,
        *,
        address_type: builtins.str,
        endpoints: typing.Sequence[typing.Union[EndpointV1Beta1, typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[EndpointPortV1Beta1, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''EndpointSlice represents a subset of the endpoints that implement a service.

        For a given service there may be multiple EndpointSlice objects, selected by labels, which must be joined to produce the full set of endpoints.

        :param address_type: addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.
        :param endpoints: endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.
        :param metadata: Standard object's metadata.
        :param ports: ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSlice
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                address_type: builtins.str,
                endpoints: typing.Sequence[typing.Union[EndpointV1Beta1, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[EndpointPortV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument address_type", value=address_type, expected_type=type_hints["address_type"])
            check_type(argname="argument endpoints", value=endpoints, expected_type=type_hints["endpoints"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
        self._values: typing.Dict[str, typing.Any] = {
            "address_type": address_type,
            "endpoints": endpoints,
        }
        if metadata is not None:
            self._values["metadata"] = metadata
        if ports is not None:
            self._values["ports"] = ports

    @builtins.property
    def address_type(self) -> builtins.str:
        '''addressType specifies the type of address carried by this EndpointSlice.

        All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSlice#addressType
        '''
        result = self._values.get("address_type")
        assert result is not None, "Required property 'address_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def endpoints(self) -> typing.List[EndpointV1Beta1]:
        '''endpoints is a list of unique endpoints in this slice.

        Each slice may include a maximum of 1000 endpoints.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSlice#endpoints
        '''
        result = self._values.get("endpoints")
        assert result is not None, "Required property 'endpoints' is missing"
        return typing.cast(typing.List[EndpointV1Beta1], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSlice#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List[EndpointPortV1Beta1]]:
        '''ports specifies the list of network ports exposed by each endpoint in this slice.

        Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates "all ports". Each slice may include a maximum of 100 ports.

        :schema: io.k8s.api.discovery.v1beta1.EndpointSlice#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List[EndpointPortV1Beta1]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEndpointSliceV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEndpoints(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEndpoints",
):
    '''Endpoints is a collection of endpoints that implement the actual service.

    Example:
    Name: "mysvc",
    Subsets: [
    {
    Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
    Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
    },
    {
    Addresses: [{"ip": "10.10.3.3"}],
    Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
    },
    ]

    :schema: io.k8s.api.core.v1.Endpoints
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subsets: typing.Optional[typing.Sequence[typing.Union[EndpointSubset, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Endpoints" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param subsets: The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                subsets: typing.Optional[typing.Sequence[typing.Union[EndpointSubset, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEndpointsProps(metadata=metadata, subsets=subsets)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subsets: typing.Optional[typing.Sequence[typing.Union[EndpointSubset, typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Endpoints".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param subsets: The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.
        '''
        props = KubeEndpointsProps(metadata=metadata, subsets=subsets)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Endpoints".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeEndpointsList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointsList",
):
    '''EndpointsList is a list of endpoints.

    :schema: io.k8s.api.core.v1.EndpointsList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointsProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.EndpointsList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of endpoints.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeEndpointsProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEndpointsListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointsProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.EndpointsList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of endpoints.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeEndpointsListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.EndpointsList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointsListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeEndpointsListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeEndpointsProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EndpointsList is a list of endpoints.

        :param items: List of endpoints.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.EndpointsList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeEndpointsProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeEndpointsProps"]:
        '''List of endpoints.

        :schema: io.k8s.api.core.v1.EndpointsList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeEndpointsProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.EndpointsList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEndpointsListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEndpointsProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "subsets": "subsets"},
)
class KubeEndpointsProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subsets: typing.Optional[typing.Sequence[typing.Union[EndpointSubset, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Endpoints is a collection of endpoints that implement the actual service.

        Example:
        Name: "mysvc",
        Subsets: [
        {
        Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
        Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
        },
        {
        Addresses: [{"ip": "10.10.3.3"}],
        Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
        },
        ]

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param subsets: The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.

        :schema: io.k8s.api.core.v1.Endpoints
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                subsets: typing.Optional[typing.Sequence[typing.Union[EndpointSubset, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument subsets", value=subsets, expected_type=type_hints["subsets"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if subsets is not None:
            self._values["subsets"] = subsets

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Endpoints#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def subsets(self) -> typing.Optional[typing.List[EndpointSubset]]:
        '''The set of all endpoints is the union of all subsets.

        Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.

        :schema: io.k8s.api.core.v1.Endpoints#subsets
        '''
        result = self._values.get("subsets")
        return typing.cast(typing.Optional[typing.List[EndpointSubset]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEndpointsProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEvent(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEvent",
):
    '''Event is a report of an event somewhere in the cluster.

    It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time.  Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason.  Events should be treated as informative, best-effort, supplemental data.

    :schema: io.k8s.api.events.v1.Event
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        event_time: datetime.datetime,
        action: typing.Optional[builtins.str] = None,
        deprecated_count: typing.Optional[jsii.Number] = None,
        deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        note: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
        regarding: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        related: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        reporting_controller: typing.Optional[builtins.str] = None,
        reporting_instance: typing.Optional[builtins.str] = None,
        series: typing.Optional[typing.Union[EventSeries, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Defines a "io.k8s.api.events.v1.Event" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param event_time: eventTime is the time when this Event was first observed. It is required.
        :param action: action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field cannot be empty for new Events and it can have at most 128 characters.
        :param deprecated_count: deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_first_timestamp: deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_last_timestamp: deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_source: deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param note: note is a human-readable description of the status of this operation. Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.
        :param reason: reason is why the action was taken. It is human-readable. This field cannot be empty for new Events and it can have at most 128 characters.
        :param regarding: regarding contains the object this Event is about. In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.
        :param related: related is the optional secondary object for more complex actions. E.g. when regarding object triggers a creation or deletion of related object.
        :param reporting_controller: reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.
        :param reporting_instance: reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.
        :param series: series is data about the Event series this event represents or nil if it's a singleton Event.
        :param type: type is the type of this event (Normal, Warning), new types could be added in the future. It is machine-readable. This field cannot be empty for new Events.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                event_time: datetime.datetime,
                action: typing.Optional[builtins.str] = None,
                deprecated_count: typing.Optional[jsii.Number] = None,
                deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                note: typing.Optional[builtins.str] = None,
                reason: typing.Optional[builtins.str] = None,
                regarding: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                related: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                reporting_controller: typing.Optional[builtins.str] = None,
                reporting_instance: typing.Optional[builtins.str] = None,
                series: typing.Optional[typing.Union[EventSeries, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEventProps(
            event_time=event_time,
            action=action,
            deprecated_count=deprecated_count,
            deprecated_first_timestamp=deprecated_first_timestamp,
            deprecated_last_timestamp=deprecated_last_timestamp,
            deprecated_source=deprecated_source,
            metadata=metadata,
            note=note,
            reason=reason,
            regarding=regarding,
            related=related,
            reporting_controller=reporting_controller,
            reporting_instance=reporting_instance,
            series=series,
            type=type,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        event_time: datetime.datetime,
        action: typing.Optional[builtins.str] = None,
        deprecated_count: typing.Optional[jsii.Number] = None,
        deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        note: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
        regarding: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        related: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        reporting_controller: typing.Optional[builtins.str] = None,
        reporting_instance: typing.Optional[builtins.str] = None,
        series: typing.Optional[typing.Union[EventSeries, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.events.v1.Event".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param event_time: eventTime is the time when this Event was first observed. It is required.
        :param action: action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field cannot be empty for new Events and it can have at most 128 characters.
        :param deprecated_count: deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_first_timestamp: deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_last_timestamp: deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_source: deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param note: note is a human-readable description of the status of this operation. Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.
        :param reason: reason is why the action was taken. It is human-readable. This field cannot be empty for new Events and it can have at most 128 characters.
        :param regarding: regarding contains the object this Event is about. In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.
        :param related: related is the optional secondary object for more complex actions. E.g. when regarding object triggers a creation or deletion of related object.
        :param reporting_controller: reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.
        :param reporting_instance: reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.
        :param series: series is data about the Event series this event represents or nil if it's a singleton Event.
        :param type: type is the type of this event (Normal, Warning), new types could be added in the future. It is machine-readable. This field cannot be empty for new Events.
        '''
        props = KubeEventProps(
            event_time=event_time,
            action=action,
            deprecated_count=deprecated_count,
            deprecated_first_timestamp=deprecated_first_timestamp,
            deprecated_last_timestamp=deprecated_last_timestamp,
            deprecated_source=deprecated_source,
            metadata=metadata,
            note=note,
            reason=reason,
            regarding=regarding,
            related=related,
            reporting_controller=reporting_controller,
            reporting_instance=reporting_instance,
            series=series,
            type=type,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.events.v1.Event".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeEventList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEventList",
):
    '''EventList is a list of Event objects.

    :schema: io.k8s.api.events.v1.EventList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeEventProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.events.v1.EventList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeEventProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEventListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeEventProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.events.v1.EventList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeEventListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.events.v1.EventList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEventListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeEventListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeEventProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EventList is a list of Event objects.

        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.events.v1.EventList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeEventProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeEventProps"]:
        '''items is a list of schema objects.

        :schema: io.k8s.api.events.v1.EventList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeEventProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.events.v1.EventList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEventListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEventListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEventListV1Beta1",
):
    '''EventList is a list of Event objects.

    :schema: io.k8s.api.events.v1beta1.EventList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeEventV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.events.v1beta1.EventList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeEventV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEventListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeEventV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.events.v1beta1.EventList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeEventListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.events.v1beta1.EventList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEventListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeEventListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeEventV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''EventList is a list of Event objects.

        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.events.v1beta1.EventList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeEventV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeEventV1Beta1Props"]:
        '''items is a list of schema objects.

        :schema: io.k8s.api.events.v1beta1.EventList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeEventV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.events.v1beta1.EventList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEventListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEventProps",
    jsii_struct_bases=[],
    name_mapping={
        "event_time": "eventTime",
        "action": "action",
        "deprecated_count": "deprecatedCount",
        "deprecated_first_timestamp": "deprecatedFirstTimestamp",
        "deprecated_last_timestamp": "deprecatedLastTimestamp",
        "deprecated_source": "deprecatedSource",
        "metadata": "metadata",
        "note": "note",
        "reason": "reason",
        "regarding": "regarding",
        "related": "related",
        "reporting_controller": "reportingController",
        "reporting_instance": "reportingInstance",
        "series": "series",
        "type": "type",
    },
)
class KubeEventProps:
    def __init__(
        self,
        *,
        event_time: datetime.datetime,
        action: typing.Optional[builtins.str] = None,
        deprecated_count: typing.Optional[jsii.Number] = None,
        deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        note: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
        regarding: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        related: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        reporting_controller: typing.Optional[builtins.str] = None,
        reporting_instance: typing.Optional[builtins.str] = None,
        series: typing.Optional[typing.Union[EventSeries, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Event is a report of an event somewhere in the cluster.

        It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time.  Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason.  Events should be treated as informative, best-effort, supplemental data.

        :param event_time: eventTime is the time when this Event was first observed. It is required.
        :param action: action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field cannot be empty for new Events and it can have at most 128 characters.
        :param deprecated_count: deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_first_timestamp: deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_last_timestamp: deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_source: deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param note: note is a human-readable description of the status of this operation. Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.
        :param reason: reason is why the action was taken. It is human-readable. This field cannot be empty for new Events and it can have at most 128 characters.
        :param regarding: regarding contains the object this Event is about. In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.
        :param related: related is the optional secondary object for more complex actions. E.g. when regarding object triggers a creation or deletion of related object.
        :param reporting_controller: reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.
        :param reporting_instance: reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.
        :param series: series is data about the Event series this event represents or nil if it's a singleton Event.
        :param type: type is the type of this event (Normal, Warning), new types could be added in the future. It is machine-readable. This field cannot be empty for new Events.

        :schema: io.k8s.api.events.v1.Event
        '''
        if isinstance(deprecated_source, dict):
            deprecated_source = EventSource(**deprecated_source)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(regarding, dict):
            regarding = ObjectReference(**regarding)
        if isinstance(related, dict):
            related = ObjectReference(**related)
        if isinstance(series, dict):
            series = EventSeries(**series)
        if __debug__:
            def stub(
                *,
                event_time: datetime.datetime,
                action: typing.Optional[builtins.str] = None,
                deprecated_count: typing.Optional[jsii.Number] = None,
                deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                note: typing.Optional[builtins.str] = None,
                reason: typing.Optional[builtins.str] = None,
                regarding: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                related: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                reporting_controller: typing.Optional[builtins.str] = None,
                reporting_instance: typing.Optional[builtins.str] = None,
                series: typing.Optional[typing.Union[EventSeries, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument event_time", value=event_time, expected_type=type_hints["event_time"])
            check_type(argname="argument action", value=action, expected_type=type_hints["action"])
            check_type(argname="argument deprecated_count", value=deprecated_count, expected_type=type_hints["deprecated_count"])
            check_type(argname="argument deprecated_first_timestamp", value=deprecated_first_timestamp, expected_type=type_hints["deprecated_first_timestamp"])
            check_type(argname="argument deprecated_last_timestamp", value=deprecated_last_timestamp, expected_type=type_hints["deprecated_last_timestamp"])
            check_type(argname="argument deprecated_source", value=deprecated_source, expected_type=type_hints["deprecated_source"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument note", value=note, expected_type=type_hints["note"])
            check_type(argname="argument reason", value=reason, expected_type=type_hints["reason"])
            check_type(argname="argument regarding", value=regarding, expected_type=type_hints["regarding"])
            check_type(argname="argument related", value=related, expected_type=type_hints["related"])
            check_type(argname="argument reporting_controller", value=reporting_controller, expected_type=type_hints["reporting_controller"])
            check_type(argname="argument reporting_instance", value=reporting_instance, expected_type=type_hints["reporting_instance"])
            check_type(argname="argument series", value=series, expected_type=type_hints["series"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {
            "event_time": event_time,
        }
        if action is not None:
            self._values["action"] = action
        if deprecated_count is not None:
            self._values["deprecated_count"] = deprecated_count
        if deprecated_first_timestamp is not None:
            self._values["deprecated_first_timestamp"] = deprecated_first_timestamp
        if deprecated_last_timestamp is not None:
            self._values["deprecated_last_timestamp"] = deprecated_last_timestamp
        if deprecated_source is not None:
            self._values["deprecated_source"] = deprecated_source
        if metadata is not None:
            self._values["metadata"] = metadata
        if note is not None:
            self._values["note"] = note
        if reason is not None:
            self._values["reason"] = reason
        if regarding is not None:
            self._values["regarding"] = regarding
        if related is not None:
            self._values["related"] = related
        if reporting_controller is not None:
            self._values["reporting_controller"] = reporting_controller
        if reporting_instance is not None:
            self._values["reporting_instance"] = reporting_instance
        if series is not None:
            self._values["series"] = series
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def event_time(self) -> datetime.datetime:
        '''eventTime is the time when this Event was first observed.

        It is required.

        :schema: io.k8s.api.events.v1.Event#eventTime
        '''
        result = self._values.get("event_time")
        assert result is not None, "Required property 'event_time' is missing"
        return typing.cast(datetime.datetime, result)

    @builtins.property
    def action(self) -> typing.Optional[builtins.str]:
        '''action is what action was taken/failed regarding to the regarding object.

        It is machine-readable. This field cannot be empty for new Events and it can have at most 128 characters.

        :schema: io.k8s.api.events.v1.Event#action
        '''
        result = self._values.get("action")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def deprecated_count(self) -> typing.Optional[jsii.Number]:
        '''deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1.Event#deprecatedCount
        '''
        result = self._values.get("deprecated_count")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def deprecated_first_timestamp(self) -> typing.Optional[datetime.datetime]:
        '''deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1.Event#deprecatedFirstTimestamp
        '''
        result = self._values.get("deprecated_first_timestamp")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def deprecated_last_timestamp(self) -> typing.Optional[datetime.datetime]:
        '''deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1.Event#deprecatedLastTimestamp
        '''
        result = self._values.get("deprecated_last_timestamp")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def deprecated_source(self) -> typing.Optional[EventSource]:
        '''deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1.Event#deprecatedSource
        '''
        result = self._values.get("deprecated_source")
        return typing.cast(typing.Optional[EventSource], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.events.v1.Event#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def note(self) -> typing.Optional[builtins.str]:
        '''note is a human-readable description of the status of this operation.

        Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.

        :schema: io.k8s.api.events.v1.Event#note
        '''
        result = self._values.get("note")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def reason(self) -> typing.Optional[builtins.str]:
        '''reason is why the action was taken.

        It is human-readable. This field cannot be empty for new Events and it can have at most 128 characters.

        :schema: io.k8s.api.events.v1.Event#reason
        '''
        result = self._values.get("reason")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def regarding(self) -> typing.Optional["ObjectReference"]:
        '''regarding contains the object this Event is about.

        In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.

        :schema: io.k8s.api.events.v1.Event#regarding
        '''
        result = self._values.get("regarding")
        return typing.cast(typing.Optional["ObjectReference"], result)

    @builtins.property
    def related(self) -> typing.Optional["ObjectReference"]:
        '''related is the optional secondary object for more complex actions.

        E.g. when regarding object triggers a creation or deletion of related object.

        :schema: io.k8s.api.events.v1.Event#related
        '''
        result = self._values.get("related")
        return typing.cast(typing.Optional["ObjectReference"], result)

    @builtins.property
    def reporting_controller(self) -> typing.Optional[builtins.str]:
        '''reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.

        :schema: io.k8s.api.events.v1.Event#reportingController
        '''
        result = self._values.get("reporting_controller")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def reporting_instance(self) -> typing.Optional[builtins.str]:
        '''reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.

        :schema: io.k8s.api.events.v1.Event#reportingInstance
        '''
        result = self._values.get("reporting_instance")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def series(self) -> typing.Optional[EventSeries]:
        '''series is data about the Event series this event represents or nil if it's a singleton Event.

        :schema: io.k8s.api.events.v1.Event#series
        '''
        result = self._values.get("series")
        return typing.cast(typing.Optional[EventSeries], result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''type is the type of this event (Normal, Warning), new types could be added in the future.

        It is machine-readable. This field cannot be empty for new Events.

        :schema: io.k8s.api.events.v1.Event#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEventProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEventV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEventV1Beta1",
):
    '''Event is a report of an event somewhere in the cluster.

    It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time.  Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason.  Events should be treated as informative, best-effort, supplemental data.

    :schema: io.k8s.api.events.v1beta1.Event
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        event_time: datetime.datetime,
        action: typing.Optional[builtins.str] = None,
        deprecated_count: typing.Optional[jsii.Number] = None,
        deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        note: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
        regarding: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        related: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        reporting_controller: typing.Optional[builtins.str] = None,
        reporting_instance: typing.Optional[builtins.str] = None,
        series: typing.Optional[typing.Union[EventSeriesV1Beta1, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Defines a "io.k8s.api.events.v1beta1.Event" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param event_time: eventTime is the time when this Event was first observed. It is required.
        :param action: action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field can have at most 128 characters.
        :param deprecated_count: deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_first_timestamp: deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_last_timestamp: deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_source: deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param note: note is a human-readable description of the status of this operation. Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.
        :param reason: reason is why the action was taken. It is human-readable. This field can have at most 128 characters.
        :param regarding: regarding contains the object this Event is about. In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.
        :param related: related is the optional secondary object for more complex actions. E.g. when regarding object triggers a creation or deletion of related object.
        :param reporting_controller: reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.
        :param reporting_instance: reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.
        :param series: series is data about the Event series this event represents or nil if it's a singleton Event.
        :param type: type is the type of this event (Normal, Warning), new types could be added in the future. It is machine-readable.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                event_time: datetime.datetime,
                action: typing.Optional[builtins.str] = None,
                deprecated_count: typing.Optional[jsii.Number] = None,
                deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                note: typing.Optional[builtins.str] = None,
                reason: typing.Optional[builtins.str] = None,
                regarding: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                related: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                reporting_controller: typing.Optional[builtins.str] = None,
                reporting_instance: typing.Optional[builtins.str] = None,
                series: typing.Optional[typing.Union[EventSeriesV1Beta1, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEventV1Beta1Props(
            event_time=event_time,
            action=action,
            deprecated_count=deprecated_count,
            deprecated_first_timestamp=deprecated_first_timestamp,
            deprecated_last_timestamp=deprecated_last_timestamp,
            deprecated_source=deprecated_source,
            metadata=metadata,
            note=note,
            reason=reason,
            regarding=regarding,
            related=related,
            reporting_controller=reporting_controller,
            reporting_instance=reporting_instance,
            series=series,
            type=type,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        event_time: datetime.datetime,
        action: typing.Optional[builtins.str] = None,
        deprecated_count: typing.Optional[jsii.Number] = None,
        deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        note: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
        regarding: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        related: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        reporting_controller: typing.Optional[builtins.str] = None,
        reporting_instance: typing.Optional[builtins.str] = None,
        series: typing.Optional[typing.Union[EventSeriesV1Beta1, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.events.v1beta1.Event".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param event_time: eventTime is the time when this Event was first observed. It is required.
        :param action: action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field can have at most 128 characters.
        :param deprecated_count: deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_first_timestamp: deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_last_timestamp: deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_source: deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param note: note is a human-readable description of the status of this operation. Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.
        :param reason: reason is why the action was taken. It is human-readable. This field can have at most 128 characters.
        :param regarding: regarding contains the object this Event is about. In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.
        :param related: related is the optional secondary object for more complex actions. E.g. when regarding object triggers a creation or deletion of related object.
        :param reporting_controller: reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.
        :param reporting_instance: reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.
        :param series: series is data about the Event series this event represents or nil if it's a singleton Event.
        :param type: type is the type of this event (Normal, Warning), new types could be added in the future. It is machine-readable.
        '''
        props = KubeEventV1Beta1Props(
            event_time=event_time,
            action=action,
            deprecated_count=deprecated_count,
            deprecated_first_timestamp=deprecated_first_timestamp,
            deprecated_last_timestamp=deprecated_last_timestamp,
            deprecated_source=deprecated_source,
            metadata=metadata,
            note=note,
            reason=reason,
            regarding=regarding,
            related=related,
            reporting_controller=reporting_controller,
            reporting_instance=reporting_instance,
            series=series,
            type=type,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.events.v1beta1.Event".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEventV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={
        "event_time": "eventTime",
        "action": "action",
        "deprecated_count": "deprecatedCount",
        "deprecated_first_timestamp": "deprecatedFirstTimestamp",
        "deprecated_last_timestamp": "deprecatedLastTimestamp",
        "deprecated_source": "deprecatedSource",
        "metadata": "metadata",
        "note": "note",
        "reason": "reason",
        "regarding": "regarding",
        "related": "related",
        "reporting_controller": "reportingController",
        "reporting_instance": "reportingInstance",
        "series": "series",
        "type": "type",
    },
)
class KubeEventV1Beta1Props:
    def __init__(
        self,
        *,
        event_time: datetime.datetime,
        action: typing.Optional[builtins.str] = None,
        deprecated_count: typing.Optional[jsii.Number] = None,
        deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
        deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        note: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
        regarding: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        related: typing.Optional[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]] = None,
        reporting_controller: typing.Optional[builtins.str] = None,
        reporting_instance: typing.Optional[builtins.str] = None,
        series: typing.Optional[typing.Union[EventSeriesV1Beta1, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Event is a report of an event somewhere in the cluster.

        It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time.  Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason.  Events should be treated as informative, best-effort, supplemental data.

        :param event_time: eventTime is the time when this Event was first observed. It is required.
        :param action: action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field can have at most 128 characters.
        :param deprecated_count: deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_first_timestamp: deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_last_timestamp: deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param deprecated_source: deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param note: note is a human-readable description of the status of this operation. Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.
        :param reason: reason is why the action was taken. It is human-readable. This field can have at most 128 characters.
        :param regarding: regarding contains the object this Event is about. In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.
        :param related: related is the optional secondary object for more complex actions. E.g. when regarding object triggers a creation or deletion of related object.
        :param reporting_controller: reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.
        :param reporting_instance: reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.
        :param series: series is data about the Event series this event represents or nil if it's a singleton Event.
        :param type: type is the type of this event (Normal, Warning), new types could be added in the future. It is machine-readable.

        :schema: io.k8s.api.events.v1beta1.Event
        '''
        if isinstance(deprecated_source, dict):
            deprecated_source = EventSource(**deprecated_source)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(regarding, dict):
            regarding = ObjectReference(**regarding)
        if isinstance(related, dict):
            related = ObjectReference(**related)
        if isinstance(series, dict):
            series = EventSeriesV1Beta1(**series)
        if __debug__:
            def stub(
                *,
                event_time: datetime.datetime,
                action: typing.Optional[builtins.str] = None,
                deprecated_count: typing.Optional[jsii.Number] = None,
                deprecated_first_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_last_timestamp: typing.Optional[datetime.datetime] = None,
                deprecated_source: typing.Optional[typing.Union[EventSource, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                note: typing.Optional[builtins.str] = None,
                reason: typing.Optional[builtins.str] = None,
                regarding: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                related: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                reporting_controller: typing.Optional[builtins.str] = None,
                reporting_instance: typing.Optional[builtins.str] = None,
                series: typing.Optional[typing.Union[EventSeriesV1Beta1, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument event_time", value=event_time, expected_type=type_hints["event_time"])
            check_type(argname="argument action", value=action, expected_type=type_hints["action"])
            check_type(argname="argument deprecated_count", value=deprecated_count, expected_type=type_hints["deprecated_count"])
            check_type(argname="argument deprecated_first_timestamp", value=deprecated_first_timestamp, expected_type=type_hints["deprecated_first_timestamp"])
            check_type(argname="argument deprecated_last_timestamp", value=deprecated_last_timestamp, expected_type=type_hints["deprecated_last_timestamp"])
            check_type(argname="argument deprecated_source", value=deprecated_source, expected_type=type_hints["deprecated_source"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument note", value=note, expected_type=type_hints["note"])
            check_type(argname="argument reason", value=reason, expected_type=type_hints["reason"])
            check_type(argname="argument regarding", value=regarding, expected_type=type_hints["regarding"])
            check_type(argname="argument related", value=related, expected_type=type_hints["related"])
            check_type(argname="argument reporting_controller", value=reporting_controller, expected_type=type_hints["reporting_controller"])
            check_type(argname="argument reporting_instance", value=reporting_instance, expected_type=type_hints["reporting_instance"])
            check_type(argname="argument series", value=series, expected_type=type_hints["series"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {
            "event_time": event_time,
        }
        if action is not None:
            self._values["action"] = action
        if deprecated_count is not None:
            self._values["deprecated_count"] = deprecated_count
        if deprecated_first_timestamp is not None:
            self._values["deprecated_first_timestamp"] = deprecated_first_timestamp
        if deprecated_last_timestamp is not None:
            self._values["deprecated_last_timestamp"] = deprecated_last_timestamp
        if deprecated_source is not None:
            self._values["deprecated_source"] = deprecated_source
        if metadata is not None:
            self._values["metadata"] = metadata
        if note is not None:
            self._values["note"] = note
        if reason is not None:
            self._values["reason"] = reason
        if regarding is not None:
            self._values["regarding"] = regarding
        if related is not None:
            self._values["related"] = related
        if reporting_controller is not None:
            self._values["reporting_controller"] = reporting_controller
        if reporting_instance is not None:
            self._values["reporting_instance"] = reporting_instance
        if series is not None:
            self._values["series"] = series
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def event_time(self) -> datetime.datetime:
        '''eventTime is the time when this Event was first observed.

        It is required.

        :schema: io.k8s.api.events.v1beta1.Event#eventTime
        '''
        result = self._values.get("event_time")
        assert result is not None, "Required property 'event_time' is missing"
        return typing.cast(datetime.datetime, result)

    @builtins.property
    def action(self) -> typing.Optional[builtins.str]:
        '''action is what action was taken/failed regarding to the regarding object.

        It is machine-readable. This field can have at most 128 characters.

        :schema: io.k8s.api.events.v1beta1.Event#action
        '''
        result = self._values.get("action")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def deprecated_count(self) -> typing.Optional[jsii.Number]:
        '''deprecatedCount is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1beta1.Event#deprecatedCount
        '''
        result = self._values.get("deprecated_count")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def deprecated_first_timestamp(self) -> typing.Optional[datetime.datetime]:
        '''deprecatedFirstTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1beta1.Event#deprecatedFirstTimestamp
        '''
        result = self._values.get("deprecated_first_timestamp")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def deprecated_last_timestamp(self) -> typing.Optional[datetime.datetime]:
        '''deprecatedLastTimestamp is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1beta1.Event#deprecatedLastTimestamp
        '''
        result = self._values.get("deprecated_last_timestamp")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def deprecated_source(self) -> typing.Optional[EventSource]:
        '''deprecatedSource is the deprecated field assuring backward compatibility with core.v1 Event type.

        :schema: io.k8s.api.events.v1beta1.Event#deprecatedSource
        '''
        result = self._values.get("deprecated_source")
        return typing.cast(typing.Optional[EventSource], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.events.v1beta1.Event#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def note(self) -> typing.Optional[builtins.str]:
        '''note is a human-readable description of the status of this operation.

        Maximal length of the note is 1kB, but libraries should be prepared to handle values up to 64kB.

        :schema: io.k8s.api.events.v1beta1.Event#note
        '''
        result = self._values.get("note")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def reason(self) -> typing.Optional[builtins.str]:
        '''reason is why the action was taken.

        It is human-readable. This field can have at most 128 characters.

        :schema: io.k8s.api.events.v1beta1.Event#reason
        '''
        result = self._values.get("reason")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def regarding(self) -> typing.Optional["ObjectReference"]:
        '''regarding contains the object this Event is about.

        In most cases it's an Object reporting controller implements, e.g. ReplicaSetController implements ReplicaSets and this event is emitted because it acts on some changes in a ReplicaSet object.

        :schema: io.k8s.api.events.v1beta1.Event#regarding
        '''
        result = self._values.get("regarding")
        return typing.cast(typing.Optional["ObjectReference"], result)

    @builtins.property
    def related(self) -> typing.Optional["ObjectReference"]:
        '''related is the optional secondary object for more complex actions.

        E.g. when regarding object triggers a creation or deletion of related object.

        :schema: io.k8s.api.events.v1beta1.Event#related
        '''
        result = self._values.get("related")
        return typing.cast(typing.Optional["ObjectReference"], result)

    @builtins.property
    def reporting_controller(self) -> typing.Optional[builtins.str]:
        '''reportingController is the name of the controller that emitted this Event, e.g. ``kubernetes.io/kubelet``. This field cannot be empty for new Events.

        :schema: io.k8s.api.events.v1beta1.Event#reportingController
        '''
        result = self._values.get("reporting_controller")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def reporting_instance(self) -> typing.Optional[builtins.str]:
        '''reportingInstance is the ID of the controller instance, e.g. ``kubelet-xyzf``. This field cannot be empty for new Events and it can have at most 128 characters.

        :schema: io.k8s.api.events.v1beta1.Event#reportingInstance
        '''
        result = self._values.get("reporting_instance")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def series(self) -> typing.Optional[EventSeriesV1Beta1]:
        '''series is data about the Event series this event represents or nil if it's a singleton Event.

        :schema: io.k8s.api.events.v1beta1.Event#series
        '''
        result = self._values.get("series")
        return typing.cast(typing.Optional[EventSeriesV1Beta1], result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''type is the type of this event (Normal, Warning), new types could be added in the future.

        It is machine-readable.

        :schema: io.k8s.api.events.v1beta1.Event#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEventV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeEviction(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeEviction",
):
    '''Eviction evicts a pod from its node subject to certain policies and safety constraints.

    This is a subresource of Pod.  A request to cause such an eviction is created by POSTing to .../pods//evictions.

    :schema: io.k8s.api.policy.v1.Eviction
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        delete_options: typing.Optional[typing.Union[DeleteOptions, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1.Eviction" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param delete_options: DeleteOptions may be provided.
        :param metadata: ObjectMeta describes the pod that is being evicted.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                delete_options: typing.Optional[typing.Union[DeleteOptions, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeEvictionProps(delete_options=delete_options, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        delete_options: typing.Optional[typing.Union[DeleteOptions, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1.Eviction".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param delete_options: DeleteOptions may be provided.
        :param metadata: ObjectMeta describes the pod that is being evicted.
        '''
        props = KubeEvictionProps(delete_options=delete_options, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1.Eviction".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeEvictionProps",
    jsii_struct_bases=[],
    name_mapping={"delete_options": "deleteOptions", "metadata": "metadata"},
)
class KubeEvictionProps:
    def __init__(
        self,
        *,
        delete_options: typing.Optional[typing.Union[DeleteOptions, typing.Dict[str, typing.Any]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Eviction evicts a pod from its node subject to certain policies and safety constraints.

        This is a subresource of Pod.  A request to cause such an eviction is created by POSTing to .../pods//evictions.

        :param delete_options: DeleteOptions may be provided.
        :param metadata: ObjectMeta describes the pod that is being evicted.

        :schema: io.k8s.api.policy.v1.Eviction
        '''
        if isinstance(delete_options, dict):
            delete_options = DeleteOptions(**delete_options)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                delete_options: typing.Optional[typing.Union[DeleteOptions, typing.Dict[str, typing.Any]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument delete_options", value=delete_options, expected_type=type_hints["delete_options"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {}
        if delete_options is not None:
            self._values["delete_options"] = delete_options
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def delete_options(self) -> typing.Optional[DeleteOptions]:
        '''DeleteOptions may be provided.

        :schema: io.k8s.api.policy.v1.Eviction#deleteOptions
        '''
        result = self._values.get("delete_options")
        return typing.cast(typing.Optional[DeleteOptions], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''ObjectMeta describes the pod that is being evicted.

        :schema: io.k8s.api.policy.v1.Eviction#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeEvictionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeFlowSchemaListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaListV1Beta1",
):
    '''FlowSchemaList is a list of FlowSchema objects.

    :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeFlowSchemaV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta1.FlowSchemaList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: ``items`` is a list of FlowSchemas.
        :param metadata: ``metadata`` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeFlowSchemaV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeFlowSchemaListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeFlowSchemaV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta1.FlowSchemaList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: ``items`` is a list of FlowSchemas.
        :param metadata: ``metadata`` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeFlowSchemaListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta1.FlowSchemaList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeFlowSchemaListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeFlowSchemaV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''FlowSchemaList is a list of FlowSchema objects.

        :param items: ``items`` is a list of FlowSchemas.
        :param metadata: ``metadata`` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeFlowSchemaV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeFlowSchemaV1Beta1Props"]:
        '''``items`` is a list of FlowSchemas.

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeFlowSchemaV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''``metadata`` is the standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchemaList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeFlowSchemaListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeFlowSchemaListV1Beta2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaListV1Beta2",
):
    '''FlowSchemaList is a list of FlowSchema objects.

    :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeFlowSchemaV1Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta2.FlowSchemaList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: ``items`` is a list of FlowSchemas.
        :param metadata: ``metadata`` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeFlowSchemaV1Beta2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeFlowSchemaListV1Beta2Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeFlowSchemaV1Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta2.FlowSchemaList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: ``items`` is a list of FlowSchemas.
        :param metadata: ``metadata`` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeFlowSchemaListV1Beta2Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta2.FlowSchemaList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaListV1Beta2Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeFlowSchemaListV1Beta2Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeFlowSchemaV1Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''FlowSchemaList is a list of FlowSchema objects.

        :param items: ``items`` is a list of FlowSchemas.
        :param metadata: ``metadata`` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeFlowSchemaV1Beta2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeFlowSchemaV1Beta2Props"]:
        '''``items`` is a list of FlowSchemas.

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeFlowSchemaV1Beta2Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''``metadata`` is the standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchemaList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeFlowSchemaListV1Beta2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeFlowSchemaV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaV1Beta1",
):
    '''FlowSchema defines the schema of a group of flows.

    Note that a flow is made up of a set of inbound API requests with similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher".

    :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchema
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta1.FlowSchema" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeFlowSchemaV1Beta1Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta1.FlowSchema".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeFlowSchemaV1Beta1Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta1.FlowSchema".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeFlowSchemaV1Beta1Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''FlowSchema defines the schema of a group of flows.

        Note that a flow is made up of a set of inbound API requests with similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher".

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchema
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = FlowSchemaSpecV1Beta1(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''``metadata`` is the standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchema#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[FlowSchemaSpecV1Beta1]:
        '''``spec`` is the specification of the desired behavior of a FlowSchema.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta1.FlowSchema#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[FlowSchemaSpecV1Beta1], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeFlowSchemaV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeFlowSchemaV1Beta2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaV1Beta2",
):
    '''FlowSchema defines the schema of a group of flows.

    Note that a flow is made up of a set of inbound API requests with similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher".

    :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchema
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta2.FlowSchema" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeFlowSchemaV1Beta2Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta2.FlowSchema".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeFlowSchemaV1Beta2Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta2.FlowSchema".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeFlowSchemaV1Beta2Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeFlowSchemaV1Beta2Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''FlowSchema defines the schema of a group of flows.

        Note that a flow is made up of a set of inbound API requests with similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher".

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchema
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = FlowSchemaSpecV1Beta2(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[FlowSchemaSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''``metadata`` is the standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchema#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[FlowSchemaSpecV1Beta2]:
        '''``spec`` is the specification of the desired behavior of a FlowSchema.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta2.FlowSchema#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[FlowSchemaSpecV1Beta2], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeFlowSchemaV1Beta2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeHorizontalPodAutoscaler(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscaler",
):
    '''configuration of a horizontal pod autoscaler.

    :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        '''
        props = KubeHorizontalPodAutoscalerProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeHorizontalPodAutoscalerList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerList",
):
    '''list of horizontal pod autoscaler objects.

    :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: list of horizontal pod autoscaler objects.
        :param metadata: Standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: list of horizontal pod autoscaler objects.
        :param metadata: Standard list metadata.
        '''
        props = KubeHorizontalPodAutoscalerListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeHorizontalPodAutoscalerListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''list of horizontal pod autoscaler objects.

        :param items: list of horizontal pod autoscaler objects.
        :param metadata: Standard list metadata.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeHorizontalPodAutoscalerProps"]:
        '''list of horizontal pod autoscaler objects.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeHorizontalPodAutoscalerProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeHorizontalPodAutoscalerListV2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListV2",
):
    '''HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects.

    :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerV2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerListV2Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.
        '''
        props = KubeHorizontalPodAutoscalerListV2Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeHorizontalPodAutoscalerListV2Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListV2Beta1",
):
    '''HorizontalPodAutoscaler is a list of horizontal pod autoscaler objects.

    :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerV2Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerListV2Beta1Props(
            items=items, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.
        '''
        props = KubeHorizontalPodAutoscalerListV2Beta1Props(
            items=items, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListV2Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeHorizontalPodAutoscalerListV2Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscaler is a list of horizontal pod autoscaler objects.

        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerV2Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeHorizontalPodAutoscalerV2Beta1Props"]:
        '''items is the list of horizontal pod autoscaler objects.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeHorizontalPodAutoscalerV2Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''metadata is the standard list metadata.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerListV2Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeHorizontalPodAutoscalerListV2Beta2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListV2Beta2",
):
    '''HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects.

    :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerV2Beta2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerListV2Beta2Props(
            items=items, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.
        '''
        props = KubeHorizontalPodAutoscalerListV2Beta2Props(
            items=items, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListV2Beta2Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeHorizontalPodAutoscalerListV2Beta2Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects.

        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerV2Beta2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeHorizontalPodAutoscalerV2Beta2Props"]:
        '''items is the list of horizontal pod autoscaler objects.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeHorizontalPodAutoscalerV2Beta2Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''metadata is the standard list metadata.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerListV2Beta2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerListV2Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeHorizontalPodAutoscalerListV2Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeHorizontalPodAutoscalerV2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects.

        :param items: items is the list of horizontal pod autoscaler objects.
        :param metadata: metadata is the standard list metadata.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeHorizontalPodAutoscalerV2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeHorizontalPodAutoscalerV2Props"]:
        '''items is the list of horizontal pod autoscaler objects.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeHorizontalPodAutoscalerV2Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''metadata is the standard list metadata.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscalerList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerListV2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeHorizontalPodAutoscalerProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''configuration of a horizontal pod autoscaler.

        :param metadata: Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = HorizontalPodAutoscalerSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[HorizontalPodAutoscalerSpec]:
        '''behaviour of autoscaler.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.

        :schema: io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[HorizontalPodAutoscalerSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeHorizontalPodAutoscalerV2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerV2",
):
    '''HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.

    :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerV2Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.
        '''
        props = KubeHorizontalPodAutoscalerV2Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeHorizontalPodAutoscalerV2Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerV2Beta1",
):
    '''HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.

    :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerV2Beta1Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.
        '''
        props = KubeHorizontalPodAutoscalerV2Beta1Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerV2Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeHorizontalPodAutoscalerV2Beta1Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.

        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = HorizontalPodAutoscalerSpecV2Beta1(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''metadata is the standard object metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[HorizontalPodAutoscalerSpecV2Beta1]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[HorizontalPodAutoscalerSpecV2Beta1], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerV2Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeHorizontalPodAutoscalerV2Beta2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerV2Beta2",
):
    '''HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.

    :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeHorizontalPodAutoscalerV2Beta2Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.
        '''
        props = KubeHorizontalPodAutoscalerV2Beta2Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerV2Beta2Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeHorizontalPodAutoscalerV2Beta2Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.

        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = HorizontalPodAutoscalerSpecV2Beta2(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''metadata is the standard object metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[HorizontalPodAutoscalerSpecV2Beta2]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[HorizontalPodAutoscalerSpecV2Beta2], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerV2Beta2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeHorizontalPodAutoscalerV2Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeHorizontalPodAutoscalerV2Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.

        :param metadata: metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: 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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = HorizontalPodAutoscalerSpecV2(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[HorizontalPodAutoscalerSpecV2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''metadata is the standard object metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[HorizontalPodAutoscalerSpecV2]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.HorizontalPodAutoscaler#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[HorizontalPodAutoscalerSpecV2], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeHorizontalPodAutoscalerV2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeIngress(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeIngress",
):
    '''Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend.

    An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.

    :schema: io.k8s.api.networking.v1.Ingress
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[IngressSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.networking.v1.Ingress" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[IngressSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeIngressProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[IngressSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.networking.v1.Ingress".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeIngressProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.networking.v1.Ingress".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeIngressClass(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeIngressClass",
):
    '''IngressClass represents the class of the Ingress, referenced by the Ingress Spec.

    The ``ingressclass.kubernetes.io/is-default-class`` annotation can be used to indicate that an IngressClass should be considered default. When a single IngressClass resource has this annotation set to true, new Ingress resources without a class specified will be assigned this default class.

    :schema: io.k8s.api.networking.v1.IngressClass
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[IngressClassSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.networking.v1.IngressClass" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[IngressClassSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeIngressClassProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[IngressClassSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.networking.v1.IngressClass".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeIngressClassProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.networking.v1.IngressClass".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeIngressClassList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeIngressClassList",
):
    '''IngressClassList is a collection of IngressClasses.

    :schema: io.k8s.api.networking.v1.IngressClassList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeIngressClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.networking.v1.IngressClassList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of IngressClasses.
        :param metadata: Standard list metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeIngressClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeIngressClassListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeIngressClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.networking.v1.IngressClassList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of IngressClasses.
        :param metadata: Standard list metadata.
        '''
        props = KubeIngressClassListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.networking.v1.IngressClassList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeIngressClassListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeIngressClassListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeIngressClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressClassList is a collection of IngressClasses.

        :param items: Items is the list of IngressClasses.
        :param metadata: Standard list metadata.

        :schema: io.k8s.api.networking.v1.IngressClassList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeIngressClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeIngressClassProps"]:
        '''Items is the list of IngressClasses.

        :schema: io.k8s.api.networking.v1.IngressClassList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeIngressClassProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        :schema: io.k8s.api.networking.v1.IngressClassList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeIngressClassListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeIngressClassProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeIngressClassProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[IngressClassSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressClass represents the class of the Ingress, referenced by the Ingress Spec.

        The ``ingressclass.kubernetes.io/is-default-class`` annotation can be used to indicate that an IngressClass should be considered default. When a single IngressClass resource has this annotation set to true, new Ingress resources without a class specified will be assigned this default class.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.networking.v1.IngressClass
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = IngressClassSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[IngressClassSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.IngressClass#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[IngressClassSpec]:
        '''Spec is the desired state of the IngressClass.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.networking.v1.IngressClass#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[IngressClassSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeIngressClassProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeIngressList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeIngressList",
):
    '''IngressList is a collection of Ingress.

    :schema: io.k8s.api.networking.v1.IngressList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeIngressProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.networking.v1.IngressList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of Ingress.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeIngressProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeIngressListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeIngressProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.networking.v1.IngressList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of Ingress.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeIngressListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.networking.v1.IngressList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeIngressListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeIngressListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeIngressProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''IngressList is a collection of Ingress.

        :param items: Items is the list of Ingress.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.IngressList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeIngressProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeIngressProps"]:
        '''Items is the list of Ingress.

        :schema: io.k8s.api.networking.v1.IngressList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeIngressProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.IngressList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeIngressListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeIngressProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeIngressProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[IngressSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend.

        An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.networking.v1.Ingress
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = IngressSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[IngressSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.Ingress#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[IngressSpec]:
        '''Spec is the desired state of the Ingress.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.networking.v1.Ingress#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[IngressSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeIngressProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeJob(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeJob",
):
    '''Job represents the configuration of a single job.

    :schema: io.k8s.api.batch.v1.Job
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.batch.v1.Job" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a job. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeJobProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.batch.v1.Job".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a job. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeJobProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.batch.v1.Job".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeJobList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeJobList",
):
    '''JobList is a collection of jobs.

    :schema: io.k8s.api.batch.v1.JobList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeJobProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.batch.v1.JobList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of Jobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeJobProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeJobListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeJobProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.batch.v1.JobList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of Jobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeJobListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.batch.v1.JobList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeJobListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeJobListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeJobProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''JobList is a collection of jobs.

        :param items: items is the list of Jobs.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.JobList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeJobProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeJobProps"]:
        '''items is the list of Jobs.

        :schema: io.k8s.api.batch.v1.JobList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeJobProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.JobList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeJobListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeJobProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeJobProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Job represents the configuration of a single job.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of a job. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1.Job
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = JobSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[JobSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.batch.v1.Job#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional[JobSpec]:
        '''Specification of the desired behavior of a job.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.batch.v1.Job#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[JobSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeJobProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeLease(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeLease",
):
    '''Lease defines a lease concept.

    :schema: io.k8s.api.coordination.v1.Lease
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["LeaseSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.coordination.v1.Lease" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param spec: Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[LeaseSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeLeaseProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["LeaseSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.coordination.v1.Lease".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param spec: Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeLeaseProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.coordination.v1.Lease".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeLeaseList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeLeaseList",
):
    '''LeaseList is a list of Lease objects.

    :schema: io.k8s.api.coordination.v1.LeaseList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeLeaseProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.coordination.v1.LeaseList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeLeaseProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeLeaseListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeLeaseProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.coordination.v1.LeaseList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeLeaseListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.coordination.v1.LeaseList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeLeaseListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeLeaseListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeLeaseProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LeaseList is a list of Lease objects.

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.coordination.v1.LeaseList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeLeaseProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeLeaseProps"]:
        '''Items is a list of schema objects.

        :schema: io.k8s.api.coordination.v1.LeaseList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeLeaseProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.coordination.v1.LeaseList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeLeaseListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeLeaseProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeLeaseProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["LeaseSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Lease defines a lease concept.

        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param spec: Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.coordination.v1.Lease
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = LeaseSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[LeaseSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.coordination.v1.Lease#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["LeaseSpec"]:
        '''Specification of the Lease.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.coordination.v1.Lease#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["LeaseSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeLeaseProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeLimitRange(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeLimitRange",
):
    '''LimitRange sets resource usage limits for each kind of resource in a Namespace.

    :schema: io.k8s.api.core.v1.LimitRange
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["LimitRangeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.LimitRange" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the limits enforced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[LimitRangeSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeLimitRangeProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["LimitRangeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.LimitRange".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the limits enforced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeLimitRangeProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.LimitRange".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeLimitRangeList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeLimitRangeList",
):
    '''LimitRangeList is a list of LimitRange items.

    :schema: io.k8s.api.core.v1.LimitRangeList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeLimitRangeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.LimitRangeList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of LimitRange objects. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeLimitRangeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeLimitRangeListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeLimitRangeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.LimitRangeList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of LimitRange objects. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeLimitRangeListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.LimitRangeList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeLimitRangeListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeLimitRangeListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeLimitRangeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LimitRangeList is a list of LimitRange items.

        :param items: Items is a list of LimitRange objects. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.LimitRangeList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeLimitRangeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeLimitRangeProps"]:
        '''Items is a list of LimitRange objects.

        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

        :schema: io.k8s.api.core.v1.LimitRangeList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeLimitRangeProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.LimitRangeList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeLimitRangeListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeLimitRangeProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeLimitRangeProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["LimitRangeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LimitRange sets resource usage limits for each kind of resource in a Namespace.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the limits enforced. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.LimitRange
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = LimitRangeSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[LimitRangeSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.LimitRange#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["LimitRangeSpec"]:
        '''Spec defines the limits enforced.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.LimitRange#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["LimitRangeSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeLimitRangeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeLocalSubjectAccessReview(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeLocalSubjectAccessReview",
):
    '''LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace.

    Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions checking.

    :schema: io.k8s.api.authorization.v1.LocalSubjectAccessReview
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["SubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.authorization.v1.LocalSubjectAccessReview" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[SubjectAccessReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeLocalSubjectAccessReviewProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["SubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.authorization.v1.LocalSubjectAccessReview".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeLocalSubjectAccessReviewProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.authorization.v1.LocalSubjectAccessReview".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeLocalSubjectAccessReviewProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeLocalSubjectAccessReviewProps:
    def __init__(
        self,
        *,
        spec: typing.Union["SubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace.

        Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions checking.

        :param spec: Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.LocalSubjectAccessReview
        '''
        if isinstance(spec, dict):
            spec = SubjectAccessReviewSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[SubjectAccessReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "SubjectAccessReviewSpec":
        '''Spec holds information about the request being evaluated.

        spec.namespace must be equal to the namespace you made the request against.  If empty, it is defaulted.

        :schema: io.k8s.api.authorization.v1.LocalSubjectAccessReview#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("SubjectAccessReviewSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.LocalSubjectAccessReview#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeLocalSubjectAccessReviewProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeMutatingWebhookConfiguration(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeMutatingWebhookConfiguration",
):
    '''MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.

    :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        webhooks: typing.Optional[typing.Sequence[typing.Union["MutatingWebhook", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param webhooks: Webhooks is a list of webhooks and the affected resources and operations.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                webhooks: typing.Optional[typing.Sequence[typing.Union[MutatingWebhook, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeMutatingWebhookConfigurationProps(
            metadata=metadata, webhooks=webhooks
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        webhooks: typing.Optional[typing.Sequence[typing.Union["MutatingWebhook", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param webhooks: Webhooks is a list of webhooks and the affected resources and operations.
        '''
        props = KubeMutatingWebhookConfigurationProps(
            metadata=metadata, webhooks=webhooks
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeMutatingWebhookConfigurationList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeMutatingWebhookConfigurationList",
):
    '''MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.

    :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeMutatingWebhookConfigurationProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of MutatingWebhookConfiguration.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeMutatingWebhookConfigurationProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeMutatingWebhookConfigurationListProps(
            items=items, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeMutatingWebhookConfigurationProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of MutatingWebhookConfiguration.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeMutatingWebhookConfigurationListProps(
            items=items, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeMutatingWebhookConfigurationListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeMutatingWebhookConfigurationListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeMutatingWebhookConfigurationProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.

        :param items: List of MutatingWebhookConfiguration.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeMutatingWebhookConfigurationProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeMutatingWebhookConfigurationProps"]:
        '''List of MutatingWebhookConfiguration.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeMutatingWebhookConfigurationProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeMutatingWebhookConfigurationListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeMutatingWebhookConfigurationProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "webhooks": "webhooks"},
)
class KubeMutatingWebhookConfigurationProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        webhooks: typing.Optional[typing.Sequence[typing.Union["MutatingWebhook", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.

        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param webhooks: Webhooks is a list of webhooks and the affected resources and operations.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                webhooks: typing.Optional[typing.Sequence[typing.Union[MutatingWebhook, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument webhooks", value=webhooks, expected_type=type_hints["webhooks"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if webhooks is not None:
            self._values["webhooks"] = webhooks

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object metadata;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def webhooks(self) -> typing.Optional[typing.List["MutatingWebhook"]]:
        '''Webhooks is a list of webhooks and the affected resources and operations.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhookConfiguration#webhooks
        '''
        result = self._values.get("webhooks")
        return typing.cast(typing.Optional[typing.List["MutatingWebhook"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeMutatingWebhookConfigurationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeNamespace(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeNamespace",
):
    '''Namespace provides a scope for Names.

    Use of multiple namespaces is optional.

    :schema: io.k8s.api.core.v1.Namespace
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NamespaceSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Namespace" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of the Namespace. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[NamespaceSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeNamespaceProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NamespaceSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Namespace".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of the Namespace. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeNamespaceProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Namespace".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeNamespaceList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeNamespaceList",
):
    '''NamespaceList is a list of Namespaces.

    :schema: io.k8s.api.core.v1.NamespaceList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeNamespaceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.NamespaceList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of Namespace objects in the list. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeNamespaceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeNamespaceListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeNamespaceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.NamespaceList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of Namespace objects in the list. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeNamespaceListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.NamespaceList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeNamespaceListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeNamespaceListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeNamespaceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''NamespaceList is a list of Namespaces.

        :param items: Items is the list of Namespace objects in the list. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.NamespaceList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeNamespaceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeNamespaceProps"]:
        '''Items is the list of Namespace objects in the list.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

        :schema: io.k8s.api.core.v1.NamespaceList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeNamespaceProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.NamespaceList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeNamespaceListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeNamespaceProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeNamespaceProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NamespaceSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Namespace provides a scope for Names.

        Use of multiple namespaces is optional.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of the Namespace. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Namespace
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = NamespaceSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[NamespaceSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Namespace#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["NamespaceSpec"]:
        '''Spec defines the behavior of the Namespace.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Namespace#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["NamespaceSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeNamespaceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeNetworkPolicy(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeNetworkPolicy",
):
    '''NetworkPolicy describes what network traffic is allowed for a set of Pods.

    :schema: io.k8s.api.networking.v1.NetworkPolicy
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NetworkPolicySpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.networking.v1.NetworkPolicy" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior for this NetworkPolicy.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[NetworkPolicySpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeNetworkPolicyProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NetworkPolicySpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.networking.v1.NetworkPolicy".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior for this NetworkPolicy.
        '''
        props = KubeNetworkPolicyProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.networking.v1.NetworkPolicy".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeNetworkPolicyList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeNetworkPolicyList",
):
    '''NetworkPolicyList is a list of NetworkPolicy objects.

    :schema: io.k8s.api.networking.v1.NetworkPolicyList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeNetworkPolicyProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.networking.v1.NetworkPolicyList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeNetworkPolicyProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeNetworkPolicyListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeNetworkPolicyProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.networking.v1.NetworkPolicyList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeNetworkPolicyListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.networking.v1.NetworkPolicyList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeNetworkPolicyListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeNetworkPolicyListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeNetworkPolicyProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''NetworkPolicyList is a list of NetworkPolicy objects.

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.NetworkPolicyList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeNetworkPolicyProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeNetworkPolicyProps"]:
        '''Items is a list of schema objects.

        :schema: io.k8s.api.networking.v1.NetworkPolicyList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeNetworkPolicyProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.NetworkPolicyList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeNetworkPolicyListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeNetworkPolicyProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeNetworkPolicyProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NetworkPolicySpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''NetworkPolicy describes what network traffic is allowed for a set of Pods.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior for this NetworkPolicy.

        :schema: io.k8s.api.networking.v1.NetworkPolicy
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = NetworkPolicySpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[NetworkPolicySpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.networking.v1.NetworkPolicy#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["NetworkPolicySpec"]:
        '''Specification of the desired behavior for this NetworkPolicy.

        :schema: io.k8s.api.networking.v1.NetworkPolicy#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["NetworkPolicySpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeNetworkPolicyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeNode(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeNode",
):
    '''Node is a worker node in Kubernetes.

    Each node will have a unique identifier in the cache (i.e. in etcd).

    :schema: io.k8s.api.core.v1.Node
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NodeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Node" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of a node. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[NodeSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeNodeProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NodeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Node".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of a node. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeNodeProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Node".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeNodeList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeNodeList",
):
    '''NodeList is the whole list of all Nodes which have been registered with master.

    :schema: io.k8s.api.core.v1.NodeList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeNodeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.NodeList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of nodes.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeNodeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeNodeListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeNodeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.NodeList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of nodes.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeNodeListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.NodeList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeNodeListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeNodeListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeNodeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''NodeList is the whole list of all Nodes which have been registered with master.

        :param items: List of nodes.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.NodeList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeNodeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeNodeProps"]:
        '''List of nodes.

        :schema: io.k8s.api.core.v1.NodeList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeNodeProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.NodeList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeNodeListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeNodeProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeNodeProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["NodeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Node is a worker node in Kubernetes.

        Each node will have a unique identifier in the cache (i.e. in etcd).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of a node. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Node
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = NodeSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[NodeSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Node#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["NodeSpec"]:
        '''Spec defines the behavior of a node.

        https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Node#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["NodeSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeNodeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePersistentVolume(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolume",
):
    '''PersistentVolume (PV) is a storage resource provisioned by an administrator.

    It is analogous to a node. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes

    :schema: io.k8s.api.core.v1.PersistentVolume
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PersistentVolumeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PersistentVolume" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines a specification of a persistent volume owned by the cluster. Provisioned by an administrator. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PersistentVolumeSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePersistentVolumeProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PersistentVolumeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PersistentVolume".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines a specification of a persistent volume owned by the cluster. Provisioned by an administrator. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
        '''
        props = KubePersistentVolumeProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PersistentVolume".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubePersistentVolumeClaim(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeClaim",
):
    '''PersistentVolumeClaim is a user's request for and claim to a persistent volume.

    :schema: io.k8s.api.core.v1.PersistentVolumeClaim
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PersistentVolumeClaimSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PersistentVolumeClaim" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired characteristics of a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PersistentVolumeClaimSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePersistentVolumeClaimProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PersistentVolumeClaimSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PersistentVolumeClaim".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired characteristics of a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        '''
        props = KubePersistentVolumeClaimProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PersistentVolumeClaim".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubePersistentVolumeClaimList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeClaimList",
):
    '''PersistentVolumeClaimList is a list of PersistentVolumeClaim items.

    :schema: io.k8s.api.core.v1.PersistentVolumeClaimList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePersistentVolumeClaimProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PersistentVolumeClaimList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: A list of persistent volume claims. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePersistentVolumeClaimProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePersistentVolumeClaimListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePersistentVolumeClaimProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PersistentVolumeClaimList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: A list of persistent volume claims. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubePersistentVolumeClaimListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PersistentVolumeClaimList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeClaimListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePersistentVolumeClaimListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePersistentVolumeClaimProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PersistentVolumeClaimList is a list of PersistentVolumeClaim items.

        :param items: A list of persistent volume claims. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePersistentVolumeClaimProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePersistentVolumeClaimProps"]:
        '''A list of persistent volume claims.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePersistentVolumeClaimProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePersistentVolumeClaimListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeClaimProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePersistentVolumeClaimProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PersistentVolumeClaimSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PersistentVolumeClaim is a user's request for and claim to a persistent volume.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired characteristics of a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

        :schema: io.k8s.api.core.v1.PersistentVolumeClaim
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PersistentVolumeClaimSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PersistentVolumeClaimSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.PersistentVolumeClaim#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PersistentVolumeClaimSpec"]:
        '''Spec defines the desired characteristics of a volume requested by a pod author.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

        :schema: io.k8s.api.core.v1.PersistentVolumeClaim#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PersistentVolumeClaimSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePersistentVolumeClaimProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePersistentVolumeList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeList",
):
    '''PersistentVolumeList is a list of PersistentVolume items.

    :schema: io.k8s.api.core.v1.PersistentVolumeList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePersistentVolumeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PersistentVolumeList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of persistent volumes. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePersistentVolumeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePersistentVolumeListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePersistentVolumeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PersistentVolumeList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of persistent volumes. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubePersistentVolumeListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PersistentVolumeList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePersistentVolumeListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePersistentVolumeProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PersistentVolumeList is a list of PersistentVolume items.

        :param items: List of persistent volumes. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PersistentVolumeList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePersistentVolumeProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePersistentVolumeProps"]:
        '''List of persistent volumes.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes

        :schema: io.k8s.api.core.v1.PersistentVolumeList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePersistentVolumeProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PersistentVolumeList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePersistentVolumeListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePersistentVolumeProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePersistentVolumeProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PersistentVolumeSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PersistentVolume (PV) is a storage resource provisioned by an administrator.

        It is analogous to a node. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines a specification of a persistent volume owned by the cluster. Provisioned by an administrator. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes

        :schema: io.k8s.api.core.v1.PersistentVolume
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PersistentVolumeSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PersistentVolumeSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.PersistentVolume#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PersistentVolumeSpec"]:
        '''Spec defines a specification of a persistent volume owned by the cluster.

        Provisioned by an administrator. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes

        :schema: io.k8s.api.core.v1.PersistentVolume#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PersistentVolumeSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePersistentVolumeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePod(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePod",
):
    '''Pod is a collection of containers that can run on a host.

    This resource is created by clients and scheduled onto hosts.

    :schema: io.k8s.api.core.v1.Pod
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Pod" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Pod".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubePodProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Pod".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubePodDisruptionBudget(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudget",
):
    '''PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods.

    :schema: io.k8s.api.policy.v1.PodDisruptionBudget
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodDisruptionBudgetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1.PodDisruptionBudget" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the PodDisruptionBudget.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodDisruptionBudgetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodDisruptionBudgetProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodDisruptionBudgetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1.PodDisruptionBudget".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the PodDisruptionBudget.
        '''
        props = KubePodDisruptionBudgetProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1.PodDisruptionBudget".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubePodDisruptionBudgetList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetList",
):
    '''PodDisruptionBudgetList is a collection of PodDisruptionBudgets.

    :schema: io.k8s.api.policy.v1.PodDisruptionBudgetList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePodDisruptionBudgetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1.PodDisruptionBudgetList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of PodDisruptionBudgets.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePodDisruptionBudgetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodDisruptionBudgetListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePodDisruptionBudgetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1.PodDisruptionBudgetList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of PodDisruptionBudgets.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubePodDisruptionBudgetListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1.PodDisruptionBudgetList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePodDisruptionBudgetListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePodDisruptionBudgetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodDisruptionBudgetList is a collection of PodDisruptionBudgets.

        :param items: Items is a list of PodDisruptionBudgets.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePodDisruptionBudgetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePodDisruptionBudgetProps"]:
        '''Items is a list of PodDisruptionBudgets.

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePodDisruptionBudgetProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodDisruptionBudgetListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePodDisruptionBudgetListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetListV1Beta1",
):
    '''PodDisruptionBudgetList is a collection of PodDisruptionBudgets.

    :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePodDisruptionBudgetV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1beta1.PodDisruptionBudgetList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items list individual PodDisruptionBudget objects.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePodDisruptionBudgetV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodDisruptionBudgetListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePodDisruptionBudgetV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1beta1.PodDisruptionBudgetList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items list individual PodDisruptionBudget objects.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubePodDisruptionBudgetListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1beta1.PodDisruptionBudgetList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePodDisruptionBudgetListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePodDisruptionBudgetV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodDisruptionBudgetList is a collection of PodDisruptionBudgets.

        :param items: items list individual PodDisruptionBudget objects.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePodDisruptionBudgetV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePodDisruptionBudgetV1Beta1Props"]:
        '''items list individual PodDisruptionBudget objects.

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePodDisruptionBudgetV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodDisruptionBudgetListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePodDisruptionBudgetProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodDisruptionBudgetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the PodDisruptionBudget.

        :schema: io.k8s.api.policy.v1.PodDisruptionBudget
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PodDisruptionBudgetSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodDisruptionBudgetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1.PodDisruptionBudget#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PodDisruptionBudgetSpec"]:
        '''Specification of the desired behavior of the PodDisruptionBudget.

        :schema: io.k8s.api.policy.v1.PodDisruptionBudget#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PodDisruptionBudgetSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodDisruptionBudgetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePodDisruptionBudgetV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetV1Beta1",
):
    '''PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods.

    :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudget
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodDisruptionBudgetSpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1beta1.PodDisruptionBudget" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the PodDisruptionBudget.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodDisruptionBudgetSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodDisruptionBudgetV1Beta1Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodDisruptionBudgetSpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1beta1.PodDisruptionBudget".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the PodDisruptionBudget.
        '''
        props = KubePodDisruptionBudgetV1Beta1Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1beta1.PodDisruptionBudget".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodDisruptionBudgetV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePodDisruptionBudgetV1Beta1Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodDisruptionBudgetSpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the PodDisruptionBudget.

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudget
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PodDisruptionBudgetSpecV1Beta1(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodDisruptionBudgetSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudget#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PodDisruptionBudgetSpecV1Beta1"]:
        '''Specification of the desired behavior of the PodDisruptionBudget.

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudget#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PodDisruptionBudgetSpecV1Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodDisruptionBudgetV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePodList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodList",
):
    '''PodList is a list of Pods.

    :schema: io.k8s.api.core.v1.PodList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePodProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PodList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of pods. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePodProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePodProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PodList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of pods. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubePodListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PodList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePodListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePodProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodList is a list of Pods.

        :param items: List of pods. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PodList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePodProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePodProps"]:
        '''List of pods.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md

        :schema: io.k8s.api.core.v1.PodList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePodProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PodList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePodProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Pod is a collection of containers that can run on a host.

        This resource is created by clients and scheduled onto hosts.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Pod
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PodSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Pod#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PodSpec"]:
        '''Specification of the desired behavior of the pod.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Pod#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PodSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePodSecurityPolicyListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodSecurityPolicyListV1Beta1",
):
    '''PodSecurityPolicyList is a list of PodSecurityPolicy objects.

    :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicyList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePodSecurityPolicyV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1beta1.PodSecurityPolicyList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePodSecurityPolicyV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodSecurityPolicyListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePodSecurityPolicyV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1beta1.PodSecurityPolicyList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubePodSecurityPolicyListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1beta1.PodSecurityPolicyList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodSecurityPolicyListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePodSecurityPolicyListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePodSecurityPolicyV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodSecurityPolicyList is a list of PodSecurityPolicy objects.

        :param items: items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicyList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePodSecurityPolicyV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePodSecurityPolicyV1Beta1Props"]:
        '''items is a list of schema objects.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicyList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePodSecurityPolicyV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicyList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodSecurityPolicyListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePodSecurityPolicyV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodSecurityPolicyV1Beta1",
):
    '''PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.

    Deprecated in 1.21.

    :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicy
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodSecurityPolicySpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.policy.v1beta1.PodSecurityPolicy" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: spec defines the policy enforced.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodSecurityPolicySpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodSecurityPolicyV1Beta1Props(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodSecurityPolicySpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.policy.v1beta1.PodSecurityPolicy".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: spec defines the policy enforced.
        '''
        props = KubePodSecurityPolicyV1Beta1Props(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.policy.v1beta1.PodSecurityPolicy".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodSecurityPolicyV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePodSecurityPolicyV1Beta1Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PodSecurityPolicySpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.

        Deprecated in 1.21.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: spec defines the policy enforced.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicy
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PodSecurityPolicySpecV1Beta1(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodSecurityPolicySpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicy#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PodSecurityPolicySpecV1Beta1"]:
        '''spec defines the policy enforced.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicy#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PodSecurityPolicySpecV1Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodSecurityPolicyV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePodTemplate(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodTemplate",
):
    '''PodTemplate describes a template for creating copies of a predefined pod.

    :schema: io.k8s.api.core.v1.PodTemplate
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        template: typing.Optional[typing.Union["PodTemplateSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PodTemplate" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param template: Template defines the pods that will be created from this pod template. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                template: typing.Optional[typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodTemplateProps(metadata=metadata, template=template)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        template: typing.Optional[typing.Union["PodTemplateSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PodTemplate".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param template: Template defines the pods that will be created from this pod template. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubePodTemplateProps(metadata=metadata, template=template)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PodTemplate".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubePodTemplateList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePodTemplateList",
):
    '''PodTemplateList is a list of PodTemplates.

    :schema: io.k8s.api.core.v1.PodTemplateList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePodTemplateProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.PodTemplateList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of pod templates.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePodTemplateProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePodTemplateListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePodTemplateProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.PodTemplateList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of pod templates.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubePodTemplateListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.PodTemplateList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodTemplateListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePodTemplateListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePodTemplateProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodTemplateList is a list of PodTemplates.

        :param items: List of pod templates.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PodTemplateList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePodTemplateProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePodTemplateProps"]:
        '''List of pod templates.

        :schema: io.k8s.api.core.v1.PodTemplateList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePodTemplateProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.PodTemplateList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodTemplateListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePodTemplateProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "template": "template"},
)
class KubePodTemplateProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        template: typing.Optional[typing.Union["PodTemplateSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodTemplate describes a template for creating copies of a predefined pod.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param template: Template defines the pods that will be created from this pod template. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.PodTemplate
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                template: typing.Optional[typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if template is not None:
            self._values["template"] = template

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.PodTemplate#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def template(self) -> typing.Optional["PodTemplateSpec"]:
        '''Template defines the pods that will be created from this pod template.

        https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.PodTemplate#template
        '''
        result = self._values.get("template")
        return typing.cast(typing.Optional["PodTemplateSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePodTemplateProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePriorityClass(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePriorityClass",
):
    '''PriorityClass defines mapping from a priority class name to the priority integer value.

    The value can be any valid integer.

    :schema: io.k8s.api.scheduling.v1.PriorityClass
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        value: jsii.Number,
        description: typing.Optional[builtins.str] = None,
        global_default: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        preemption_policy: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Defines a "io.k8s.api.scheduling.v1.PriorityClass" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param value: The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.
        :param description: description is an arbitrary string that usually provides guidelines on when this priority class should be used.
        :param global_default: globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as ``globalDefault``. However, if more than one PriorityClasses exists with their ``globalDefault`` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param preemption_policy: PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate. Default: PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                value: jsii.Number,
                description: typing.Optional[builtins.str] = None,
                global_default: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                preemption_policy: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePriorityClassProps(
            value=value,
            description=description,
            global_default=global_default,
            metadata=metadata,
            preemption_policy=preemption_policy,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        value: jsii.Number,
        description: typing.Optional[builtins.str] = None,
        global_default: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        preemption_policy: typing.Optional[builtins.str] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.scheduling.v1.PriorityClass".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param value: The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.
        :param description: description is an arbitrary string that usually provides guidelines on when this priority class should be used.
        :param global_default: globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as ``globalDefault``. However, if more than one PriorityClasses exists with their ``globalDefault`` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param preemption_policy: PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate. Default: PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.
        '''
        props = KubePriorityClassProps(
            value=value,
            description=description,
            global_default=global_default,
            metadata=metadata,
            preemption_policy=preemption_policy,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.scheduling.v1.PriorityClass".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubePriorityClassList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePriorityClassList",
):
    '''PriorityClassList is a collection of priority classes.

    :schema: io.k8s.api.scheduling.v1.PriorityClassList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePriorityClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.scheduling.v1.PriorityClassList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: items is the list of PriorityClasses.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePriorityClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePriorityClassListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePriorityClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.scheduling.v1.PriorityClassList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: items is the list of PriorityClasses.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubePriorityClassListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.scheduling.v1.PriorityClassList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePriorityClassListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePriorityClassListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePriorityClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityClassList is a collection of priority classes.

        :param items: items is the list of PriorityClasses.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.scheduling.v1.PriorityClassList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePriorityClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePriorityClassProps"]:
        '''items is the list of PriorityClasses.

        :schema: io.k8s.api.scheduling.v1.PriorityClassList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePriorityClassProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.scheduling.v1.PriorityClassList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePriorityClassListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePriorityClassProps",
    jsii_struct_bases=[],
    name_mapping={
        "value": "value",
        "description": "description",
        "global_default": "globalDefault",
        "metadata": "metadata",
        "preemption_policy": "preemptionPolicy",
    },
)
class KubePriorityClassProps:
    def __init__(
        self,
        *,
        value: jsii.Number,
        description: typing.Optional[builtins.str] = None,
        global_default: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        preemption_policy: typing.Optional[builtins.str] = None,
    ) -> None:
        '''PriorityClass defines mapping from a priority class name to the priority integer value.

        The value can be any valid integer.

        :param value: The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.
        :param description: description is an arbitrary string that usually provides guidelines on when this priority class should be used.
        :param global_default: globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as ``globalDefault``. However, if more than one PriorityClasses exists with their ``globalDefault`` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param preemption_policy: PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate. Default: PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.

        :schema: io.k8s.api.scheduling.v1.PriorityClass
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                value: jsii.Number,
                description: typing.Optional[builtins.str] = None,
                global_default: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                preemption_policy: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            check_type(argname="argument description", value=description, expected_type=type_hints["description"])
            check_type(argname="argument global_default", value=global_default, expected_type=type_hints["global_default"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument preemption_policy", value=preemption_policy, expected_type=type_hints["preemption_policy"])
        self._values: typing.Dict[str, typing.Any] = {
            "value": value,
        }
        if description is not None:
            self._values["description"] = description
        if global_default is not None:
            self._values["global_default"] = global_default
        if metadata is not None:
            self._values["metadata"] = metadata
        if preemption_policy is not None:
            self._values["preemption_policy"] = preemption_policy

    @builtins.property
    def value(self) -> jsii.Number:
        '''The value of this priority class.

        This is the actual priority that pods receive when they have the name of this class in their pod spec.

        :schema: io.k8s.api.scheduling.v1.PriorityClass#value
        '''
        result = self._values.get("value")
        assert result is not None, "Required property 'value' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''description is an arbitrary string that usually provides guidelines on when this priority class should be used.

        :schema: io.k8s.api.scheduling.v1.PriorityClass#description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def global_default(self) -> typing.Optional[builtins.bool]:
        '''globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class.

        Only one PriorityClass can be marked as ``globalDefault``. However, if more than one PriorityClasses exists with their ``globalDefault`` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.

        :schema: io.k8s.api.scheduling.v1.PriorityClass#globalDefault
        '''
        result = self._values.get("global_default")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.scheduling.v1.PriorityClass#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def preemption_policy(self) -> typing.Optional[builtins.str]:
        '''PreemptionPolicy is the Policy for preempting pods with lower priority.

        One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.

        :default: PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.

        :schema: io.k8s.api.scheduling.v1.PriorityClass#preemptionPolicy
        '''
        result = self._values.get("preemption_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePriorityClassProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePriorityLevelConfigurationListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationListV1Beta1",
):
    '''PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects.

    :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePriorityLevelConfigurationV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: ``items`` is a list of request-priorities.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePriorityLevelConfigurationV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePriorityLevelConfigurationListV1Beta1Props(
            items=items, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePriorityLevelConfigurationV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: ``items`` is a list of request-priorities.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubePriorityLevelConfigurationListV1Beta1Props(
            items=items, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePriorityLevelConfigurationListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePriorityLevelConfigurationV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects.

        :param items: ``items`` is a list of request-priorities.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePriorityLevelConfigurationV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePriorityLevelConfigurationV1Beta1Props"]:
        '''``items`` is a list of request-priorities.

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePriorityLevelConfigurationV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''``metadata`` is the standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePriorityLevelConfigurationListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePriorityLevelConfigurationListV1Beta2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationListV1Beta2",
):
    '''PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects.

    :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubePriorityLevelConfigurationV1Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: ``items`` is a list of request-priorities.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubePriorityLevelConfigurationV1Beta2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePriorityLevelConfigurationListV1Beta2Props(
            items=items, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubePriorityLevelConfigurationV1Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: ``items`` is a list of request-priorities.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubePriorityLevelConfigurationListV1Beta2Props(
            items=items, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationListV1Beta2Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubePriorityLevelConfigurationListV1Beta2Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubePriorityLevelConfigurationV1Beta2Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects.

        :param items: ``items`` is a list of request-priorities.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubePriorityLevelConfigurationV1Beta2Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubePriorityLevelConfigurationV1Beta2Props"]:
        '''``items`` is a list of request-priorities.

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubePriorityLevelConfigurationV1Beta2Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''``metadata`` is the standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePriorityLevelConfigurationListV1Beta2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePriorityLevelConfigurationV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationV1Beta1",
):
    '''PriorityLevelConfiguration represents the configuration of a priority level.

    :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PriorityLevelConfigurationSpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a "request-priority". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PriorityLevelConfigurationSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePriorityLevelConfigurationV1Beta1Props(
            metadata=metadata, spec=spec
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PriorityLevelConfigurationSpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a "request-priority". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubePriorityLevelConfigurationV1Beta1Props(
            metadata=metadata, spec=spec
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePriorityLevelConfigurationV1Beta1Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PriorityLevelConfigurationSpecV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityLevelConfiguration represents the configuration of a priority level.

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a "request-priority". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PriorityLevelConfigurationSpecV1Beta1(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PriorityLevelConfigurationSpecV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''``metadata`` is the standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PriorityLevelConfigurationSpecV1Beta1"]:
        '''``spec`` is the specification of the desired behavior of a "request-priority".

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PriorityLevelConfigurationSpecV1Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePriorityLevelConfigurationV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubePriorityLevelConfigurationV1Beta2(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationV1Beta2",
):
    '''PriorityLevelConfiguration represents the configuration of a priority level.

    :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PriorityLevelConfigurationSpecV1Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a "request-priority". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PriorityLevelConfigurationSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubePriorityLevelConfigurationV1Beta2Props(
            metadata=metadata, spec=spec
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PriorityLevelConfigurationSpecV1Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a "request-priority". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubePriorityLevelConfigurationV1Beta2Props(
            metadata=metadata, spec=spec
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubePriorityLevelConfigurationV1Beta2Props",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubePriorityLevelConfigurationV1Beta2Props:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["PriorityLevelConfigurationSpecV1Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityLevelConfiguration represents the configuration of a priority level.

        :param metadata: ``metadata`` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: ``spec`` is the specification of the desired behavior of a "request-priority". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PriorityLevelConfigurationSpecV1Beta2(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PriorityLevelConfigurationSpecV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''``metadata`` is the standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["PriorityLevelConfigurationSpecV1Beta2"]:
        '''``spec`` is the specification of the desired behavior of a "request-priority".

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["PriorityLevelConfigurationSpecV1Beta2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubePriorityLevelConfigurationV1Beta2Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeReplicaSet(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeReplicaSet",
):
    '''ReplicaSet ensures that a specified number of pod replicas are running at any given time.

    :schema: io.k8s.api.apps.v1.ReplicaSet
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ReplicaSetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.ReplicaSet" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the specification of the desired behavior of the ReplicaSet. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ReplicaSetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeReplicaSetProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ReplicaSetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.ReplicaSet".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the specification of the desired behavior of the ReplicaSet. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeReplicaSetProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.ReplicaSet".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeReplicaSetList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeReplicaSetList",
):
    '''ReplicaSetList is a collection of ReplicaSets.

    :schema: io.k8s.api.apps.v1.ReplicaSetList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeReplicaSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.ReplicaSetList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeReplicaSetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeReplicaSetListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeReplicaSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.ReplicaSetList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeReplicaSetListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.ReplicaSetList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeReplicaSetListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeReplicaSetListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeReplicaSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ReplicaSetList is a collection of ReplicaSets.

        :param items: List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.apps.v1.ReplicaSetList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeReplicaSetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeReplicaSetProps"]:
        '''List of ReplicaSets.

        More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller

        :schema: io.k8s.api.apps.v1.ReplicaSetList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeReplicaSetProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.apps.v1.ReplicaSetList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeReplicaSetListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeReplicaSetProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeReplicaSetProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ReplicaSetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ReplicaSet ensures that a specified number of pod replicas are running at any given time.

        :param metadata: If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the specification of the desired behavior of the ReplicaSet. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.apps.v1.ReplicaSet
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = ReplicaSetSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ReplicaSetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages.

        Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.ReplicaSet#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["ReplicaSetSpec"]:
        '''Spec defines the specification of the desired behavior of the ReplicaSet.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.apps.v1.ReplicaSet#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["ReplicaSetSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeReplicaSetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeReplicationController(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeReplicationController",
):
    '''ReplicationController represents the configuration of a replication controller.

    :schema: io.k8s.api.core.v1.ReplicationController
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ReplicationControllerSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ReplicationController" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the specification of the desired behavior of the replication controller. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ReplicationControllerSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeReplicationControllerProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ReplicationControllerSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ReplicationController".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the specification of the desired behavior of the replication controller. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeReplicationControllerProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ReplicationController".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeReplicationControllerList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeReplicationControllerList",
):
    '''ReplicationControllerList is a collection of replication controllers.

    :schema: io.k8s.api.core.v1.ReplicationControllerList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeReplicationControllerProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ReplicationControllerList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of replication controllers. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeReplicationControllerProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeReplicationControllerListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeReplicationControllerProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ReplicationControllerList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of replication controllers. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeReplicationControllerListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ReplicationControllerList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeReplicationControllerListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeReplicationControllerListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeReplicationControllerProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ReplicationControllerList is a collection of replication controllers.

        :param items: List of replication controllers. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ReplicationControllerList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeReplicationControllerProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeReplicationControllerProps"]:
        '''List of replication controllers.

        More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller

        :schema: io.k8s.api.core.v1.ReplicationControllerList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeReplicationControllerProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ReplicationControllerList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeReplicationControllerListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeReplicationControllerProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeReplicationControllerProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ReplicationControllerSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ReplicationController represents the configuration of a replication controller.

        :param metadata: If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the specification of the desired behavior of the replication controller. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.ReplicationController
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = ReplicationControllerSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ReplicationControllerSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages.

        Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ReplicationController#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["ReplicationControllerSpec"]:
        '''Spec defines the specification of the desired behavior of the replication controller.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.ReplicationController#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["ReplicationControllerSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeReplicationControllerProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeResourceQuota(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeResourceQuota",
):
    '''ResourceQuota sets aggregate quota restrictions enforced per namespace.

    :schema: io.k8s.api.core.v1.ResourceQuota
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ResourceQuotaSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ResourceQuota" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired quota. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ResourceQuotaSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeResourceQuotaProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ResourceQuotaSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ResourceQuota".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired quota. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeResourceQuotaProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ResourceQuota".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeResourceQuotaList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeResourceQuotaList",
):
    '''ResourceQuotaList is a list of ResourceQuota items.

    :schema: io.k8s.api.core.v1.ResourceQuotaList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeResourceQuotaProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ResourceQuotaList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of ResourceQuota objects. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeResourceQuotaProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeResourceQuotaListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeResourceQuotaProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ResourceQuotaList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of ResourceQuota objects. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeResourceQuotaListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ResourceQuotaList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeResourceQuotaListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeResourceQuotaListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeResourceQuotaProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ResourceQuotaList is a list of ResourceQuota items.

        :param items: Items is a list of ResourceQuota objects. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ResourceQuotaList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeResourceQuotaProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeResourceQuotaProps"]:
        '''Items is a list of ResourceQuota objects.

        More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/

        :schema: io.k8s.api.core.v1.ResourceQuotaList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeResourceQuotaProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ResourceQuotaList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeResourceQuotaListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeResourceQuotaProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeResourceQuotaProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ResourceQuotaSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ResourceQuota sets aggregate quota restrictions enforced per namespace.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired quota. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.ResourceQuota
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = ResourceQuotaSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ResourceQuotaSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ResourceQuota#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["ResourceQuotaSpec"]:
        '''Spec defines the desired quota.

        https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.ResourceQuota#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["ResourceQuotaSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeResourceQuotaProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRole(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRole",
):
    '''Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.

    :schema: io.k8s.api.rbac.v1.Role
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.Role" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata.
        :param rules: Rules holds all the PolicyRules for this Role.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[PolicyRule, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRoleProps(metadata=metadata, rules=rules)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.Role".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata.
        :param rules: Rules holds all the PolicyRules for this Role.
        '''
        props = KubeRoleProps(metadata=metadata, rules=rules)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.Role".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeRoleBinding(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRoleBinding",
):
    '''RoleBinding references a role, but does not contain it.

    It can reference a Role in the same namespace or a ClusterRole in the global namespace. It adds who information via Subjects and namespace information by which namespace it exists in.  RoleBindings in a given namespace only have effect in that namespace.

    :schema: io.k8s.api.rbac.v1.RoleBinding
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        role_ref: typing.Union["RoleRef", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subjects: typing.Optional[typing.Sequence[typing.Union["Subject", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.RoleBinding" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param role_ref: RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.
        :param metadata: Standard object's metadata.
        :param subjects: Subjects holds references to the objects the role applies to.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                role_ref: typing.Union[RoleRef, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                subjects: typing.Optional[typing.Sequence[typing.Union[Subject, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRoleBindingProps(
            role_ref=role_ref, metadata=metadata, subjects=subjects
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        role_ref: typing.Union["RoleRef", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subjects: typing.Optional[typing.Sequence[typing.Union["Subject", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.RoleBinding".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param role_ref: RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.
        :param metadata: Standard object's metadata.
        :param subjects: Subjects holds references to the objects the role applies to.
        '''
        props = KubeRoleBindingProps(
            role_ref=role_ref, metadata=metadata, subjects=subjects
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.RoleBinding".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeRoleBindingList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRoleBindingList",
):
    '''RoleBindingList is a collection of RoleBindings.

    :schema: io.k8s.api.rbac.v1.RoleBindingList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeRoleBindingProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.RoleBindingList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of RoleBindings.
        :param metadata: Standard object's metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeRoleBindingProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRoleBindingListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeRoleBindingProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.RoleBindingList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of RoleBindings.
        :param metadata: Standard object's metadata.
        '''
        props = KubeRoleBindingListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.RoleBindingList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRoleBindingListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeRoleBindingListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeRoleBindingProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RoleBindingList is a collection of RoleBindings.

        :param items: Items is a list of RoleBindings.
        :param metadata: Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.RoleBindingList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeRoleBindingProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeRoleBindingProps"]:
        '''Items is a list of RoleBindings.

        :schema: io.k8s.api.rbac.v1.RoleBindingList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeRoleBindingProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.RoleBindingList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRoleBindingListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRoleBindingProps",
    jsii_struct_bases=[],
    name_mapping={
        "role_ref": "roleRef",
        "metadata": "metadata",
        "subjects": "subjects",
    },
)
class KubeRoleBindingProps:
    def __init__(
        self,
        *,
        role_ref: typing.Union["RoleRef", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        subjects: typing.Optional[typing.Sequence[typing.Union["Subject", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''RoleBinding references a role, but does not contain it.

        It can reference a Role in the same namespace or a ClusterRole in the global namespace. It adds who information via Subjects and namespace information by which namespace it exists in.  RoleBindings in a given namespace only have effect in that namespace.

        :param role_ref: RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.
        :param metadata: Standard object's metadata.
        :param subjects: Subjects holds references to the objects the role applies to.

        :schema: io.k8s.api.rbac.v1.RoleBinding
        '''
        if isinstance(role_ref, dict):
            role_ref = RoleRef(**role_ref)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                role_ref: typing.Union[RoleRef, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                subjects: typing.Optional[typing.Sequence[typing.Union[Subject, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument role_ref", value=role_ref, expected_type=type_hints["role_ref"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument subjects", value=subjects, expected_type=type_hints["subjects"])
        self._values: typing.Dict[str, typing.Any] = {
            "role_ref": role_ref,
        }
        if metadata is not None:
            self._values["metadata"] = metadata
        if subjects is not None:
            self._values["subjects"] = subjects

    @builtins.property
    def role_ref(self) -> "RoleRef":
        '''RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace.

        If the RoleRef cannot be resolved, the Authorizer must return an error.

        :schema: io.k8s.api.rbac.v1.RoleBinding#roleRef
        '''
        result = self._values.get("role_ref")
        assert result is not None, "Required property 'role_ref' is missing"
        return typing.cast("RoleRef", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.RoleBinding#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def subjects(self) -> typing.Optional[typing.List["Subject"]]:
        '''Subjects holds references to the objects the role applies to.

        :schema: io.k8s.api.rbac.v1.RoleBinding#subjects
        '''
        result = self._values.get("subjects")
        return typing.cast(typing.Optional[typing.List["Subject"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRoleBindingProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRoleList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRoleList",
):
    '''RoleList is a collection of Roles.

    :schema: io.k8s.api.rbac.v1.RoleList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeRoleProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.rbac.v1.RoleList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of Roles.
        :param metadata: Standard object's metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeRoleProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRoleListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeRoleProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.rbac.v1.RoleList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of Roles.
        :param metadata: Standard object's metadata.
        '''
        props = KubeRoleListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.rbac.v1.RoleList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRoleListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeRoleListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeRoleProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RoleList is a collection of Roles.

        :param items: Items is a list of Roles.
        :param metadata: Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.RoleList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeRoleProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeRoleProps"]:
        '''Items is a list of Roles.

        :schema: io.k8s.api.rbac.v1.RoleList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeRoleProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.RoleList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRoleListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRoleProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "rules": "rules"},
)
class KubeRoleProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["PolicyRule", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.

        :param metadata: Standard object's metadata.
        :param rules: Rules holds all the PolicyRules for this Role.

        :schema: io.k8s.api.rbac.v1.Role
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[PolicyRule, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if rules is not None:
            self._values["rules"] = rules

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        :schema: io.k8s.api.rbac.v1.Role#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List["PolicyRule"]]:
        '''Rules holds all the PolicyRules for this Role.

        :schema: io.k8s.api.rbac.v1.Role#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List["PolicyRule"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRoleProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRuntimeClass(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClass",
):
    '''RuntimeClass defines a class of container runtime supported in the cluster.

    The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod.  For more details, see https://kubernetes.io/docs/concepts/containers/runtime-class/

    :schema: io.k8s.api.node.v1.RuntimeClass
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        handler: builtins.str,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Union["Overhead", typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["Scheduling", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.node.v1.RuntimeClass" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param handler: Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ This field is in beta starting v1.18 and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                handler: builtins.str,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                overhead: typing.Optional[typing.Union[Overhead, typing.Dict[str, typing.Any]]] = None,
                scheduling: typing.Optional[typing.Union[Scheduling, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRuntimeClassProps(
            handler=handler,
            metadata=metadata,
            overhead=overhead,
            scheduling=scheduling,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        handler: builtins.str,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Union["Overhead", typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["Scheduling", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.node.v1.RuntimeClass".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param handler: Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ This field is in beta starting v1.18 and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.
        '''
        props = KubeRuntimeClassProps(
            handler=handler,
            metadata=metadata,
            overhead=overhead,
            scheduling=scheduling,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.node.v1.RuntimeClass".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeRuntimeClassList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassList",
):
    '''RuntimeClassList is a list of RuntimeClass objects.

    :schema: io.k8s.api.node.v1.RuntimeClassList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.node.v1.RuntimeClassList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeRuntimeClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRuntimeClassListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.node.v1.RuntimeClassList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeRuntimeClassListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.node.v1.RuntimeClassList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeRuntimeClassListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClassList is a list of RuntimeClass objects.

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.node.v1.RuntimeClassList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeRuntimeClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeRuntimeClassProps"]:
        '''Items is a list of schema objects.

        :schema: io.k8s.api.node.v1.RuntimeClassList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeRuntimeClassProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.node.v1.RuntimeClassList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRuntimeClassListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRuntimeClassListV1Alpha1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassListV1Alpha1",
):
    '''RuntimeClassList is a list of RuntimeClass objects.

    :schema: io.k8s.api.node.v1alpha1.RuntimeClassList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.node.v1alpha1.RuntimeClassList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeRuntimeClassV1Alpha1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRuntimeClassListV1Alpha1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.node.v1alpha1.RuntimeClassList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeRuntimeClassListV1Alpha1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.node.v1alpha1.RuntimeClassList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassListV1Alpha1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeRuntimeClassListV1Alpha1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClassList is a list of RuntimeClass objects.

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeRuntimeClassV1Alpha1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeRuntimeClassV1Alpha1Props"]:
        '''Items is a list of schema objects.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeRuntimeClassV1Alpha1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRuntimeClassListV1Alpha1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRuntimeClassListV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassListV1Beta1",
):
    '''RuntimeClassList is a list of RuntimeClass objects.

    :schema: io.k8s.api.node.v1beta1.RuntimeClassList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.node.v1beta1.RuntimeClassList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeRuntimeClassV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRuntimeClassListV1Beta1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.node.v1beta1.RuntimeClassList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeRuntimeClassListV1Beta1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.node.v1beta1.RuntimeClassList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassListV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeRuntimeClassListV1Beta1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeRuntimeClassV1Beta1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClassList is a list of RuntimeClass objects.

        :param items: Items is a list of schema objects.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.node.v1beta1.RuntimeClassList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeRuntimeClassV1Beta1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeRuntimeClassV1Beta1Props"]:
        '''Items is a list of schema objects.

        :schema: io.k8s.api.node.v1beta1.RuntimeClassList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeRuntimeClassV1Beta1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.node.v1beta1.RuntimeClassList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRuntimeClassListV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassProps",
    jsii_struct_bases=[],
    name_mapping={
        "handler": "handler",
        "metadata": "metadata",
        "overhead": "overhead",
        "scheduling": "scheduling",
    },
)
class KubeRuntimeClassProps:
    def __init__(
        self,
        *,
        handler: builtins.str,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Union["Overhead", typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["Scheduling", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClass defines a class of container runtime supported in the cluster.

        The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod.  For more details, see https://kubernetes.io/docs/concepts/containers/runtime-class/

        :param handler: Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ This field is in beta starting v1.18 and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.

        :schema: io.k8s.api.node.v1.RuntimeClass
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(overhead, dict):
            overhead = Overhead(**overhead)
        if isinstance(scheduling, dict):
            scheduling = Scheduling(**scheduling)
        if __debug__:
            def stub(
                *,
                handler: builtins.str,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                overhead: typing.Optional[typing.Union[Overhead, typing.Dict[str, typing.Any]]] = None,
                scheduling: typing.Optional[typing.Union[Scheduling, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument handler", value=handler, expected_type=type_hints["handler"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument overhead", value=overhead, expected_type=type_hints["overhead"])
            check_type(argname="argument scheduling", value=scheduling, expected_type=type_hints["scheduling"])
        self._values: typing.Dict[str, typing.Any] = {
            "handler": handler,
        }
        if metadata is not None:
            self._values["metadata"] = metadata
        if overhead is not None:
            self._values["overhead"] = overhead
        if scheduling is not None:
            self._values["scheduling"] = scheduling

    @builtins.property
    def handler(self) -> builtins.str:
        '''Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class.

        The possible values are specific to the node & CRI configuration.  It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.

        :schema: io.k8s.api.node.v1.RuntimeClass#handler
        '''
        result = self._values.get("handler")
        assert result is not None, "Required property 'handler' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.node.v1.RuntimeClass#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def overhead(self) -> typing.Optional["Overhead"]:
        '''Overhead represents the resource overhead associated with running a pod for a given RuntimeClass.

        For more details, see
        https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/
        This field is in beta starting v1.18 and is only honored by servers that enable the PodOverhead feature.

        :schema: io.k8s.api.node.v1.RuntimeClass#overhead
        '''
        result = self._values.get("overhead")
        return typing.cast(typing.Optional["Overhead"], result)

    @builtins.property
    def scheduling(self) -> typing.Optional["Scheduling"]:
        '''Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it.

        If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.

        :schema: io.k8s.api.node.v1.RuntimeClass#scheduling
        '''
        result = self._values.get("scheduling")
        return typing.cast(typing.Optional["Scheduling"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRuntimeClassProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRuntimeClassV1Alpha1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassV1Alpha1",
):
    '''RuntimeClass defines a class of container runtime supported in the cluster.

    The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod.  For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class

    :schema: io.k8s.api.node.v1alpha1.RuntimeClass
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["RuntimeClassSpecV1Alpha1", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.node.v1alpha1.RuntimeClass" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[RuntimeClassSpecV1Alpha1, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRuntimeClassV1Alpha1Props(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["RuntimeClassSpecV1Alpha1", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.node.v1alpha1.RuntimeClass".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeRuntimeClassV1Alpha1Props(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.node.v1alpha1.RuntimeClass".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassV1Alpha1Props",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeRuntimeClassV1Alpha1Props:
    def __init__(
        self,
        *,
        spec: typing.Union["RuntimeClassSpecV1Alpha1", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClass defines a class of container runtime supported in the cluster.

        The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod.  For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class

        :param spec: Specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClass
        '''
        if isinstance(spec, dict):
            spec = RuntimeClassSpecV1Alpha1(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[RuntimeClassSpecV1Alpha1, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "RuntimeClassSpecV1Alpha1":
        '''Specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClass#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("RuntimeClassSpecV1Alpha1", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClass#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRuntimeClassV1Alpha1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeRuntimeClassV1Beta1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassV1Beta1",
):
    '''RuntimeClass defines a class of container runtime supported in the cluster.

    The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod.  For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class

    :schema: io.k8s.api.node.v1beta1.RuntimeClass
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        handler: builtins.str,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Union["OverheadV1Beta1", typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["SchedulingV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.node.v1beta1.RuntimeClass" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param handler: Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                handler: builtins.str,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                overhead: typing.Optional[typing.Union[OverheadV1Beta1, typing.Dict[str, typing.Any]]] = None,
                scheduling: typing.Optional[typing.Union[SchedulingV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeRuntimeClassV1Beta1Props(
            handler=handler,
            metadata=metadata,
            overhead=overhead,
            scheduling=scheduling,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        handler: builtins.str,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Union["OverheadV1Beta1", typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["SchedulingV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.node.v1beta1.RuntimeClass".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param handler: Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.
        '''
        props = KubeRuntimeClassV1Beta1Props(
            handler=handler,
            metadata=metadata,
            overhead=overhead,
            scheduling=scheduling,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.node.v1beta1.RuntimeClass".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeRuntimeClassV1Beta1Props",
    jsii_struct_bases=[],
    name_mapping={
        "handler": "handler",
        "metadata": "metadata",
        "overhead": "overhead",
        "scheduling": "scheduling",
    },
)
class KubeRuntimeClassV1Beta1Props:
    def __init__(
        self,
        *,
        handler: builtins.str,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Union["OverheadV1Beta1", typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["SchedulingV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClass defines a class of container runtime supported in the cluster.

        The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod.  For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class

        :param handler: Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param metadata: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.

        :schema: io.k8s.api.node.v1beta1.RuntimeClass
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(overhead, dict):
            overhead = OverheadV1Beta1(**overhead)
        if isinstance(scheduling, dict):
            scheduling = SchedulingV1Beta1(**scheduling)
        if __debug__:
            def stub(
                *,
                handler: builtins.str,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                overhead: typing.Optional[typing.Union[OverheadV1Beta1, typing.Dict[str, typing.Any]]] = None,
                scheduling: typing.Optional[typing.Union[SchedulingV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument handler", value=handler, expected_type=type_hints["handler"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument overhead", value=overhead, expected_type=type_hints["overhead"])
            check_type(argname="argument scheduling", value=scheduling, expected_type=type_hints["scheduling"])
        self._values: typing.Dict[str, typing.Any] = {
            "handler": handler,
        }
        if metadata is not None:
            self._values["metadata"] = metadata
        if overhead is not None:
            self._values["overhead"] = overhead
        if scheduling is not None:
            self._values["scheduling"] = scheduling

    @builtins.property
    def handler(self) -> builtins.str:
        '''Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class.

        The possible values are specific to the node & CRI configuration.  It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.

        :schema: io.k8s.api.node.v1beta1.RuntimeClass#handler
        '''
        result = self._values.get("handler")
        assert result is not None, "Required property 'handler' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.node.v1beta1.RuntimeClass#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def overhead(self) -> typing.Optional["OverheadV1Beta1"]:
        '''Overhead represents the resource overhead associated with running a pod for a given RuntimeClass.

        For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.

        :schema: io.k8s.api.node.v1beta1.RuntimeClass#overhead
        '''
        result = self._values.get("overhead")
        return typing.cast(typing.Optional["OverheadV1Beta1"], result)

    @builtins.property
    def scheduling(self) -> typing.Optional["SchedulingV1Beta1"]:
        '''Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it.

        If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.

        :schema: io.k8s.api.node.v1beta1.RuntimeClass#scheduling
        '''
        result = self._values.get("scheduling")
        return typing.cast(typing.Optional["SchedulingV1Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeRuntimeClassV1Beta1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeScale(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeScale",
):
    '''Scale represents a scaling request for a resource.

    :schema: io.k8s.api.autoscaling.v1.Scale
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ScaleSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.autoscaling.v1.Scale" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param spec: defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ScaleSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeScaleProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ScaleSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.autoscaling.v1.Scale".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param spec: defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
        '''
        props = KubeScaleProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.autoscaling.v1.Scale".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeScaleProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeScaleProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ScaleSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Scale represents a scaling request for a resource.

        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param spec: defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.

        :schema: io.k8s.api.autoscaling.v1.Scale
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = ScaleSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ScaleSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object metadata;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.autoscaling.v1.Scale#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["ScaleSpec"]:
        '''defines the behavior of the scale.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.

        :schema: io.k8s.api.autoscaling.v1.Scale#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["ScaleSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeScaleProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeSecret(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeSecret",
):
    '''Secret holds secret data of a certain type.

    The total bytes of the values in the Data field must be less than MaxSecretSize bytes.

    :schema: io.k8s.api.core.v1.Secret
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        immutable: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        string_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Secret" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param data: Data contains the secret data. Each key must consist of alphanumeric characters, '-', '_' or '.'. The serialized form of the secret data is a base64 encoded string, representing the arbitrary (possibly non-string) data value here. Described in https://tools.ietf.org/html/rfc4648#section-4
        :param immutable: Immutable, if set to true, ensures that data stored in the Secret cannot be updated (only object metadata can be modified). If not set to true, the field can be modified at any time. Defaulted to nil.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param string_data: stringData allows specifying non-binary secret data in string form. It is provided as a write-only input field for convenience. All keys and values are merged into the data field on write, overwriting any existing values. The stringData field is never output when reading from the API.
        :param type: Used to facilitate programmatic handling of secret data. More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                immutable: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                string_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeSecretProps(
            data=data,
            immutable=immutable,
            metadata=metadata,
            string_data=string_data,
            type=type,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        immutable: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        string_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Secret".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param data: Data contains the secret data. Each key must consist of alphanumeric characters, '-', '_' or '.'. The serialized form of the secret data is a base64 encoded string, representing the arbitrary (possibly non-string) data value here. Described in https://tools.ietf.org/html/rfc4648#section-4
        :param immutable: Immutable, if set to true, ensures that data stored in the Secret cannot be updated (only object metadata can be modified). If not set to true, the field can be modified at any time. Defaulted to nil.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param string_data: stringData allows specifying non-binary secret data in string form. It is provided as a write-only input field for convenience. All keys and values are merged into the data field on write, overwriting any existing values. The stringData field is never output when reading from the API.
        :param type: Used to facilitate programmatic handling of secret data. More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types
        '''
        props = KubeSecretProps(
            data=data,
            immutable=immutable,
            metadata=metadata,
            string_data=string_data,
            type=type,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Secret".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeSecretList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeSecretList",
):
    '''SecretList is a list of Secret.

    :schema: io.k8s.api.core.v1.SecretList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeSecretProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.SecretList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is a list of secret objects. More info: https://kubernetes.io/docs/concepts/configuration/secret
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeSecretProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeSecretListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeSecretProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.SecretList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is a list of secret objects. More info: https://kubernetes.io/docs/concepts/configuration/secret
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeSecretListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.SecretList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeSecretListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeSecretListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeSecretProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SecretList is a list of Secret.

        :param items: Items is a list of secret objects. More info: https://kubernetes.io/docs/concepts/configuration/secret
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.SecretList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeSecretProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeSecretProps"]:
        '''Items is a list of secret objects.

        More info: https://kubernetes.io/docs/concepts/configuration/secret

        :schema: io.k8s.api.core.v1.SecretList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeSecretProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.SecretList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeSecretListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeSecretProps",
    jsii_struct_bases=[],
    name_mapping={
        "data": "data",
        "immutable": "immutable",
        "metadata": "metadata",
        "string_data": "stringData",
        "type": "type",
    },
)
class KubeSecretProps:
    def __init__(
        self,
        *,
        data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        immutable: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        string_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Secret holds secret data of a certain type.

        The total bytes of the values in the Data field must be less than MaxSecretSize bytes.

        :param data: Data contains the secret data. Each key must consist of alphanumeric characters, '-', '_' or '.'. The serialized form of the secret data is a base64 encoded string, representing the arbitrary (possibly non-string) data value here. Described in https://tools.ietf.org/html/rfc4648#section-4
        :param immutable: Immutable, if set to true, ensures that data stored in the Secret cannot be updated (only object metadata can be modified). If not set to true, the field can be modified at any time. Defaulted to nil.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param string_data: stringData allows specifying non-binary secret data in string form. It is provided as a write-only input field for convenience. All keys and values are merged into the data field on write, overwriting any existing values. The stringData field is never output when reading from the API.
        :param type: Used to facilitate programmatic handling of secret data. More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types

        :schema: io.k8s.api.core.v1.Secret
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                immutable: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                string_data: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument data", value=data, expected_type=type_hints["data"])
            check_type(argname="argument immutable", value=immutable, expected_type=type_hints["immutable"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument string_data", value=string_data, expected_type=type_hints["string_data"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {}
        if data is not None:
            self._values["data"] = data
        if immutable is not None:
            self._values["immutable"] = immutable
        if metadata is not None:
            self._values["metadata"] = metadata
        if string_data is not None:
            self._values["string_data"] = string_data
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def data(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Data contains the secret data.

        Each key must consist of alphanumeric characters, '-', '_' or '.'. The serialized form of the secret data is a base64 encoded string, representing the arbitrary (possibly non-string) data value here. Described in https://tools.ietf.org/html/rfc4648#section-4

        :schema: io.k8s.api.core.v1.Secret#data
        '''
        result = self._values.get("data")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def immutable(self) -> typing.Optional[builtins.bool]:
        '''Immutable, if set to true, ensures that data stored in the Secret cannot be updated (only object metadata can be modified).

        If not set to true, the field can be modified at any time. Defaulted to nil.

        :schema: io.k8s.api.core.v1.Secret#immutable
        '''
        result = self._values.get("immutable")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Secret#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def string_data(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''stringData allows specifying non-binary secret data in string form.

        It is provided as a write-only input field for convenience. All keys and values are merged into the data field on write, overwriting any existing values. The stringData field is never output when reading from the API.

        :schema: io.k8s.api.core.v1.Secret#stringData
        '''
        result = self._values.get("string_data")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''Used to facilitate programmatic handling of secret data.

        More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types

        :schema: io.k8s.api.core.v1.Secret#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeSecretProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeSelfSubjectAccessReview(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeSelfSubjectAccessReview",
):
    '''SelfSubjectAccessReview checks whether or the current user can perform an action.

    Not filling in a spec.namespace means "in all namespaces".  Self is a special case, because users should always be able to check whether they can perform an action

    :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReview
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["SelfSubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.authorization.v1.SelfSubjectAccessReview" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec holds information about the request being evaluated. user and groups must be empty
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[SelfSubjectAccessReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeSelfSubjectAccessReviewProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["SelfSubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.authorization.v1.SelfSubjectAccessReview".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec holds information about the request being evaluated. user and groups must be empty
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeSelfSubjectAccessReviewProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.authorization.v1.SelfSubjectAccessReview".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeSelfSubjectAccessReviewProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeSelfSubjectAccessReviewProps:
    def __init__(
        self,
        *,
        spec: typing.Union["SelfSubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SelfSubjectAccessReview checks whether or the current user can perform an action.

        Not filling in a spec.namespace means "in all namespaces".  Self is a special case, because users should always be able to check whether they can perform an action

        :param spec: Spec holds information about the request being evaluated. user and groups must be empty
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReview
        '''
        if isinstance(spec, dict):
            spec = SelfSubjectAccessReviewSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[SelfSubjectAccessReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "SelfSubjectAccessReviewSpec":
        '''Spec holds information about the request being evaluated.

        user and groups must be empty

        :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReview#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("SelfSubjectAccessReviewSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReview#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeSelfSubjectAccessReviewProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeSelfSubjectRulesReview(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeSelfSubjectRulesReview",
):
    '''SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace.

    The returned list of actions may be incomplete depending on the server's authorization mode, and any errors experienced during the evaluation. SelfSubjectRulesReview should be used by UIs to show/hide actions, or to quickly let an end user reason about their permissions. It should NOT Be used by external systems to drive authorization decisions as this raises confused deputy, cache lifetime/revocation, and correctness concerns. SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server.

    :schema: io.k8s.api.authorization.v1.SelfSubjectRulesReview
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["SelfSubjectRulesReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.authorization.v1.SelfSubjectRulesReview" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[SelfSubjectRulesReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeSelfSubjectRulesReviewProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["SelfSubjectRulesReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.authorization.v1.SelfSubjectRulesReview".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeSelfSubjectRulesReviewProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.authorization.v1.SelfSubjectRulesReview".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeSelfSubjectRulesReviewProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeSelfSubjectRulesReviewProps:
    def __init__(
        self,
        *,
        spec: typing.Union["SelfSubjectRulesReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace.

        The returned list of actions may be incomplete depending on the server's authorization mode, and any errors experienced during the evaluation. SelfSubjectRulesReview should be used by UIs to show/hide actions, or to quickly let an end user reason about their permissions. It should NOT Be used by external systems to drive authorization decisions as this raises confused deputy, cache lifetime/revocation, and correctness concerns. SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server.

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.SelfSubjectRulesReview
        '''
        if isinstance(spec, dict):
            spec = SelfSubjectRulesReviewSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[SelfSubjectRulesReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "SelfSubjectRulesReviewSpec":
        '''Spec holds information about the request being evaluated.

        :schema: io.k8s.api.authorization.v1.SelfSubjectRulesReview#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("SelfSubjectRulesReviewSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.SelfSubjectRulesReview#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeSelfSubjectRulesReviewProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeService(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeService",
):
    '''Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy.

    :schema: io.k8s.api.core.v1.Service
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ServiceSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.Service" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of a service. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ServiceSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeServiceProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ServiceSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.Service".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of a service. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        '''
        props = KubeServiceProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.Service".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeServiceAccount(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeServiceAccount",
):
    '''ServiceAccount binds together: * a name, understood by users, and perhaps by peripheral systems, for an identity * a principal that can be authenticated and authorized * a set of secrets.

    :schema: io.k8s.api.core.v1.ServiceAccount
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        automount_service_account_token: typing.Optional[builtins.bool] = None,
        image_pull_secrets: typing.Optional[typing.Sequence[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        secrets: typing.Optional[typing.Sequence[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ServiceAccount" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param automount_service_account_token: AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted. Can be overridden at the pod level.
        :param image_pull_secrets: ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param secrets: Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: https://kubernetes.io/docs/concepts/configuration/secret
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                automount_service_account_token: typing.Optional[builtins.bool] = None,
                image_pull_secrets: typing.Optional[typing.Sequence[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                secrets: typing.Optional[typing.Sequence[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeServiceAccountProps(
            automount_service_account_token=automount_service_account_token,
            image_pull_secrets=image_pull_secrets,
            metadata=metadata,
            secrets=secrets,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        automount_service_account_token: typing.Optional[builtins.bool] = None,
        image_pull_secrets: typing.Optional[typing.Sequence[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        secrets: typing.Optional[typing.Sequence[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ServiceAccount".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param automount_service_account_token: AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted. Can be overridden at the pod level.
        :param image_pull_secrets: ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param secrets: Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: https://kubernetes.io/docs/concepts/configuration/secret
        '''
        props = KubeServiceAccountProps(
            automount_service_account_token=automount_service_account_token,
            image_pull_secrets=image_pull_secrets,
            metadata=metadata,
            secrets=secrets,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ServiceAccount".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeServiceAccountList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeServiceAccountList",
):
    '''ServiceAccountList is a list of ServiceAccount objects.

    :schema: io.k8s.api.core.v1.ServiceAccountList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeServiceAccountProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ServiceAccountList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of ServiceAccounts. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeServiceAccountProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeServiceAccountListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeServiceAccountProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ServiceAccountList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of ServiceAccounts. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeServiceAccountListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ServiceAccountList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeServiceAccountListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeServiceAccountListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeServiceAccountProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ServiceAccountList is a list of ServiceAccount objects.

        :param items: List of ServiceAccounts. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ServiceAccountList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeServiceAccountProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeServiceAccountProps"]:
        '''List of ServiceAccounts.

        More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

        :schema: io.k8s.api.core.v1.ServiceAccountList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeServiceAccountProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ServiceAccountList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeServiceAccountListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeServiceAccountProps",
    jsii_struct_bases=[],
    name_mapping={
        "automount_service_account_token": "automountServiceAccountToken",
        "image_pull_secrets": "imagePullSecrets",
        "metadata": "metadata",
        "secrets": "secrets",
    },
)
class KubeServiceAccountProps:
    def __init__(
        self,
        *,
        automount_service_account_token: typing.Optional[builtins.bool] = None,
        image_pull_secrets: typing.Optional[typing.Sequence[typing.Union["LocalObjectReference", typing.Dict[str, typing.Any]]]] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        secrets: typing.Optional[typing.Sequence[typing.Union["ObjectReference", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''ServiceAccount binds together: * a name, understood by users, and perhaps by peripheral systems, for an identity * a principal that can be authenticated and authorized * a set of secrets.

        :param automount_service_account_token: AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted. Can be overridden at the pod level.
        :param image_pull_secrets: ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param secrets: Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: https://kubernetes.io/docs/concepts/configuration/secret

        :schema: io.k8s.api.core.v1.ServiceAccount
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                automount_service_account_token: typing.Optional[builtins.bool] = None,
                image_pull_secrets: typing.Optional[typing.Sequence[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]]] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                secrets: typing.Optional[typing.Sequence[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument automount_service_account_token", value=automount_service_account_token, expected_type=type_hints["automount_service_account_token"])
            check_type(argname="argument image_pull_secrets", value=image_pull_secrets, expected_type=type_hints["image_pull_secrets"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument secrets", value=secrets, expected_type=type_hints["secrets"])
        self._values: typing.Dict[str, typing.Any] = {}
        if automount_service_account_token is not None:
            self._values["automount_service_account_token"] = automount_service_account_token
        if image_pull_secrets is not None:
            self._values["image_pull_secrets"] = image_pull_secrets
        if metadata is not None:
            self._values["metadata"] = metadata
        if secrets is not None:
            self._values["secrets"] = secrets

    @builtins.property
    def automount_service_account_token(self) -> typing.Optional[builtins.bool]:
        '''AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted.

        Can be overridden at the pod level.

        :schema: io.k8s.api.core.v1.ServiceAccount#automountServiceAccountToken
        '''
        result = self._values.get("automount_service_account_token")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def image_pull_secrets(
        self,
    ) -> typing.Optional[typing.List["LocalObjectReference"]]:
        '''ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount.

        ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod

        :schema: io.k8s.api.core.v1.ServiceAccount#imagePullSecrets
        '''
        result = self._values.get("image_pull_secrets")
        return typing.cast(typing.Optional[typing.List["LocalObjectReference"]], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.ServiceAccount#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def secrets(self) -> typing.Optional[typing.List["ObjectReference"]]:
        '''Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount.

        More info: https://kubernetes.io/docs/concepts/configuration/secret

        :schema: io.k8s.api.core.v1.ServiceAccount#secrets
        '''
        result = self._values.get("secrets")
        return typing.cast(typing.Optional[typing.List["ObjectReference"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeServiceAccountProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeServiceList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeServiceList",
):
    '''ServiceList holds a list of services.

    :schema: io.k8s.api.core.v1.ServiceList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeServiceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.core.v1.ServiceList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of services.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeServiceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeServiceListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeServiceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.core.v1.ServiceList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of services.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeServiceListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.core.v1.ServiceList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeServiceListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeServiceListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeServiceProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ServiceList holds a list of services.

        :param items: List of services.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ServiceList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeServiceProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeServiceProps"]:
        '''List of services.

        :schema: io.k8s.api.core.v1.ServiceList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeServiceProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ServiceList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeServiceListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeServiceProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeServiceProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["ServiceSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the behavior of a service. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Service
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = ServiceSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[ServiceSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.Service#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["ServiceSpec"]:
        '''Spec defines the behavior of a service.

        https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.Service#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["ServiceSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeServiceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeStatefulSet(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStatefulSet",
):
    '''StatefulSet represents a set of pods with consistent identities.

    Identities are defined as:

    - Network: A single stable DNS and hostname.
    - Storage: As many VolumeClaims as requested.
      The StatefulSet guarantees that a given network identity will always map to the same storage identity.

    :schema: io.k8s.api.apps.v1.StatefulSet
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["StatefulSetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.StatefulSet" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired identities of pods in this set.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[StatefulSetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStatefulSetProps(metadata=metadata, spec=spec)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["StatefulSetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.StatefulSet".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired identities of pods in this set.
        '''
        props = KubeStatefulSetProps(metadata=metadata, spec=spec)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.StatefulSet".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeStatefulSetList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStatefulSetList",
):
    '''StatefulSetList is a collection of StatefulSets.

    :schema: io.k8s.api.apps.v1.StatefulSetList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeStatefulSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apps.v1.StatefulSetList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of stateful sets.
        :param metadata: Standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeStatefulSetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStatefulSetListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeStatefulSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apps.v1.StatefulSetList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of stateful sets.
        :param metadata: Standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeStatefulSetListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apps.v1.StatefulSetList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStatefulSetListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeStatefulSetListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeStatefulSetProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''StatefulSetList is a collection of StatefulSets.

        :param items: Items is the list of stateful sets.
        :param metadata: Standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.StatefulSetList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeStatefulSetProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeStatefulSetProps"]:
        '''Items is the list of stateful sets.

        :schema: io.k8s.api.apps.v1.StatefulSetList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeStatefulSetProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.StatefulSetList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStatefulSetListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStatefulSetProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class KubeStatefulSetProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union["StatefulSetSpec", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''StatefulSet represents a set of pods with consistent identities.

        Identities are defined as:

        - Network: A single stable DNS and hostname.
        - Storage: As many VolumeClaims as requested.
          The StatefulSet guarantees that a given network identity will always map to the same storage identity.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Spec defines the desired identities of pods in this set.

        :schema: io.k8s.api.apps.v1.StatefulSet
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = StatefulSetSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[StatefulSetSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apps.v1.StatefulSet#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def spec(self) -> typing.Optional["StatefulSetSpec"]:
        '''Spec defines the desired identities of pods in this set.

        :schema: io.k8s.api.apps.v1.StatefulSet#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional["StatefulSetSpec"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStatefulSetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeStatus(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStatus",
):
    '''Status is a return value for calls that don't return other objects.

    :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        code: typing.Optional[jsii.Number] = None,
        details: typing.Optional[typing.Union["StatusDetails", typing.Dict[str, typing.Any]]] = None,
        message: typing.Optional[builtins.str] = None,
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
        reason: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Defines a "io.k8s.apimachinery.pkg.apis.meta.v1.Status" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param code: Suggested HTTP return code for this status, 0 if not set.
        :param details: Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.
        :param message: A human-readable description of the status of this operation.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        :param reason: A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                code: typing.Optional[jsii.Number] = None,
                details: typing.Optional[typing.Union[StatusDetails, typing.Dict[str, typing.Any]]] = None,
                message: typing.Optional[builtins.str] = None,
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
                reason: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStatusProps(
            code=code,
            details=details,
            message=message,
            metadata=metadata,
            reason=reason,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        code: typing.Optional[jsii.Number] = None,
        details: typing.Optional[typing.Union["StatusDetails", typing.Dict[str, typing.Any]]] = None,
        message: typing.Optional[builtins.str] = None,
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
        reason: typing.Optional[builtins.str] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.apimachinery.pkg.apis.meta.v1.Status".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param code: Suggested HTTP return code for this status, 0 if not set.
        :param details: Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.
        :param message: A human-readable description of the status of this operation.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        :param reason: A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.
        '''
        props = KubeStatusProps(
            code=code,
            details=details,
            message=message,
            metadata=metadata,
            reason=reason,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.apimachinery.pkg.apis.meta.v1.Status".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStatusProps",
    jsii_struct_bases=[],
    name_mapping={
        "code": "code",
        "details": "details",
        "message": "message",
        "metadata": "metadata",
        "reason": "reason",
    },
)
class KubeStatusProps:
    def __init__(
        self,
        *,
        code: typing.Optional[jsii.Number] = None,
        details: typing.Optional[typing.Union["StatusDetails", typing.Dict[str, typing.Any]]] = None,
        message: typing.Optional[builtins.str] = None,
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
        reason: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Status is a return value for calls that don't return other objects.

        :param code: Suggested HTTP return code for this status, 0 if not set.
        :param details: Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.
        :param message: A human-readable description of the status of this operation.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        :param reason: A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status
        '''
        if isinstance(details, dict):
            details = StatusDetails(**details)
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                code: typing.Optional[jsii.Number] = None,
                details: typing.Optional[typing.Union[StatusDetails, typing.Dict[str, typing.Any]]] = None,
                message: typing.Optional[builtins.str] = None,
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
                reason: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument code", value=code, expected_type=type_hints["code"])
            check_type(argname="argument details", value=details, expected_type=type_hints["details"])
            check_type(argname="argument message", value=message, expected_type=type_hints["message"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument reason", value=reason, expected_type=type_hints["reason"])
        self._values: typing.Dict[str, typing.Any] = {}
        if code is not None:
            self._values["code"] = code
        if details is not None:
            self._values["details"] = details
        if message is not None:
            self._values["message"] = message
        if metadata is not None:
            self._values["metadata"] = metadata
        if reason is not None:
            self._values["reason"] = reason

    @builtins.property
    def code(self) -> typing.Optional[jsii.Number]:
        '''Suggested HTTP return code for this status, 0 if not set.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status#code
        '''
        result = self._values.get("code")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def details(self) -> typing.Optional["StatusDetails"]:
        '''Extended data associated with the reason.

        Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status#details
        '''
        result = self._values.get("details")
        return typing.cast(typing.Optional["StatusDetails"], result)

    @builtins.property
    def message(self) -> typing.Optional[builtins.str]:
        '''A human-readable description of the status of this operation.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status#message
        '''
        result = self._values.get("message")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    @builtins.property
    def reason(self) -> typing.Optional[builtins.str]:
        '''A machine-readable description of why this operation is in the "Failure" status.

        If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Status#reason
        '''
        result = self._values.get("reason")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStatusProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeStorageClass(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStorageClass",
):
    '''StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.

    StorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.

    :schema: io.k8s.api.storage.v1.StorageClass
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        provisioner: builtins.str,
        allowed_topologies: typing.Optional[typing.Sequence[typing.Union["TopologySelectorTerm", typing.Dict[str, typing.Any]]]] = None,
        allow_volume_expansion: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
        parameters: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        reclaim_policy: typing.Optional[builtins.str] = None,
        volume_binding_mode: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.StorageClass" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param provisioner: Provisioner indicates the type of the provisioner.
        :param allowed_topologies: Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.
        :param allow_volume_expansion: AllowVolumeExpansion shows whether the storage class allow volume expand.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param mount_options: Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the PVs will simply fail if one is invalid.
        :param parameters: Parameters holds the parameters for the provisioner that should create volumes of this storage class.
        :param reclaim_policy: Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete. Default: Delete.
        :param volume_binding_mode: VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                provisioner: builtins.str,
                allowed_topologies: typing.Optional[typing.Sequence[typing.Union[TopologySelectorTerm, typing.Dict[str, typing.Any]]]] = None,
                allow_volume_expansion: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
                parameters: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                reclaim_policy: typing.Optional[builtins.str] = None,
                volume_binding_mode: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStorageClassProps(
            provisioner=provisioner,
            allowed_topologies=allowed_topologies,
            allow_volume_expansion=allow_volume_expansion,
            metadata=metadata,
            mount_options=mount_options,
            parameters=parameters,
            reclaim_policy=reclaim_policy,
            volume_binding_mode=volume_binding_mode,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        provisioner: builtins.str,
        allowed_topologies: typing.Optional[typing.Sequence[typing.Union["TopologySelectorTerm", typing.Dict[str, typing.Any]]]] = None,
        allow_volume_expansion: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
        parameters: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        reclaim_policy: typing.Optional[builtins.str] = None,
        volume_binding_mode: typing.Optional[builtins.str] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.StorageClass".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param provisioner: Provisioner indicates the type of the provisioner.
        :param allowed_topologies: Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.
        :param allow_volume_expansion: AllowVolumeExpansion shows whether the storage class allow volume expand.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param mount_options: Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the PVs will simply fail if one is invalid.
        :param parameters: Parameters holds the parameters for the provisioner that should create volumes of this storage class.
        :param reclaim_policy: Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete. Default: Delete.
        :param volume_binding_mode: VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.
        '''
        props = KubeStorageClassProps(
            provisioner=provisioner,
            allowed_topologies=allowed_topologies,
            allow_volume_expansion=allow_volume_expansion,
            metadata=metadata,
            mount_options=mount_options,
            parameters=parameters,
            reclaim_policy=reclaim_policy,
            volume_binding_mode=volume_binding_mode,
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.StorageClass".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeStorageClassList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStorageClassList",
):
    '''StorageClassList is a collection of storage classes.

    :schema: io.k8s.api.storage.v1.StorageClassList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeStorageClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.StorageClassList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of StorageClasses.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeStorageClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStorageClassListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeStorageClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.StorageClassList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of StorageClasses.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeStorageClassListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.StorageClassList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStorageClassListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeStorageClassListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeStorageClassProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''StorageClassList is a collection of storage classes.

        :param items: Items is the list of StorageClasses.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.StorageClassList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeStorageClassProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeStorageClassProps"]:
        '''Items is the list of StorageClasses.

        :schema: io.k8s.api.storage.v1.StorageClassList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeStorageClassProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.StorageClassList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStorageClassListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStorageClassProps",
    jsii_struct_bases=[],
    name_mapping={
        "provisioner": "provisioner",
        "allowed_topologies": "allowedTopologies",
        "allow_volume_expansion": "allowVolumeExpansion",
        "metadata": "metadata",
        "mount_options": "mountOptions",
        "parameters": "parameters",
        "reclaim_policy": "reclaimPolicy",
        "volume_binding_mode": "volumeBindingMode",
    },
)
class KubeStorageClassProps:
    def __init__(
        self,
        *,
        provisioner: builtins.str,
        allowed_topologies: typing.Optional[typing.Sequence[typing.Union["TopologySelectorTerm", typing.Dict[str, typing.Any]]]] = None,
        allow_volume_expansion: typing.Optional[builtins.bool] = None,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
        parameters: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        reclaim_policy: typing.Optional[builtins.str] = None,
        volume_binding_mode: typing.Optional[builtins.str] = None,
    ) -> None:
        '''StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.

        StorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.

        :param provisioner: Provisioner indicates the type of the provisioner.
        :param allowed_topologies: Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.
        :param allow_volume_expansion: AllowVolumeExpansion shows whether the storage class allow volume expand.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param mount_options: Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the PVs will simply fail if one is invalid.
        :param parameters: Parameters holds the parameters for the provisioner that should create volumes of this storage class.
        :param reclaim_policy: Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete. Default: Delete.
        :param volume_binding_mode: VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.

        :schema: io.k8s.api.storage.v1.StorageClass
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                provisioner: builtins.str,
                allowed_topologies: typing.Optional[typing.Sequence[typing.Union[TopologySelectorTerm, typing.Dict[str, typing.Any]]]] = None,
                allow_volume_expansion: typing.Optional[builtins.bool] = None,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
                parameters: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                reclaim_policy: typing.Optional[builtins.str] = None,
                volume_binding_mode: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument provisioner", value=provisioner, expected_type=type_hints["provisioner"])
            check_type(argname="argument allowed_topologies", value=allowed_topologies, expected_type=type_hints["allowed_topologies"])
            check_type(argname="argument allow_volume_expansion", value=allow_volume_expansion, expected_type=type_hints["allow_volume_expansion"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument mount_options", value=mount_options, expected_type=type_hints["mount_options"])
            check_type(argname="argument parameters", value=parameters, expected_type=type_hints["parameters"])
            check_type(argname="argument reclaim_policy", value=reclaim_policy, expected_type=type_hints["reclaim_policy"])
            check_type(argname="argument volume_binding_mode", value=volume_binding_mode, expected_type=type_hints["volume_binding_mode"])
        self._values: typing.Dict[str, typing.Any] = {
            "provisioner": provisioner,
        }
        if allowed_topologies is not None:
            self._values["allowed_topologies"] = allowed_topologies
        if allow_volume_expansion is not None:
            self._values["allow_volume_expansion"] = allow_volume_expansion
        if metadata is not None:
            self._values["metadata"] = metadata
        if mount_options is not None:
            self._values["mount_options"] = mount_options
        if parameters is not None:
            self._values["parameters"] = parameters
        if reclaim_policy is not None:
            self._values["reclaim_policy"] = reclaim_policy
        if volume_binding_mode is not None:
            self._values["volume_binding_mode"] = volume_binding_mode

    @builtins.property
    def provisioner(self) -> builtins.str:
        '''Provisioner indicates the type of the provisioner.

        :schema: io.k8s.api.storage.v1.StorageClass#provisioner
        '''
        result = self._values.get("provisioner")
        assert result is not None, "Required property 'provisioner' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def allowed_topologies(
        self,
    ) -> typing.Optional[typing.List["TopologySelectorTerm"]]:
        '''Restrict the node topologies where volumes can be dynamically provisioned.

        Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.

        :schema: io.k8s.api.storage.v1.StorageClass#allowedTopologies
        '''
        result = self._values.get("allowed_topologies")
        return typing.cast(typing.Optional[typing.List["TopologySelectorTerm"]], result)

    @builtins.property
    def allow_volume_expansion(self) -> typing.Optional[builtins.bool]:
        '''AllowVolumeExpansion shows whether the storage class allow volume expand.

        :schema: io.k8s.api.storage.v1.StorageClass#allowVolumeExpansion
        '''
        result = self._values.get("allow_volume_expansion")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1.StorageClass#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def mount_options(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the PVs will simply fail if one is invalid.

        :schema: io.k8s.api.storage.v1.StorageClass#mountOptions
        '''
        result = self._values.get("mount_options")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def parameters(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Parameters holds the parameters for the provisioner that should create volumes of this storage class.

        :schema: io.k8s.api.storage.v1.StorageClass#parameters
        '''
        result = self._values.get("parameters")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def reclaim_policy(self) -> typing.Optional[builtins.str]:
        '''Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy.

        Defaults to Delete.

        :default: Delete.

        :schema: io.k8s.api.storage.v1.StorageClass#reclaimPolicy
        '''
        result = self._values.get("reclaim_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_binding_mode(self) -> typing.Optional[builtins.str]:
        '''VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound.

        When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.

        :schema: io.k8s.api.storage.v1.StorageClass#volumeBindingMode
        '''
        result = self._values.get("volume_binding_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStorageClassProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeStorageVersionListV1Alpha1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStorageVersionListV1Alpha1",
):
    '''A list of StorageVersions.

    :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeStorageVersionV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items holds a list of StorageVersion.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeStorageVersionV1Alpha1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStorageVersionListV1Alpha1Props(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeStorageVersionV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items holds a list of StorageVersion.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeStorageVersionListV1Alpha1Props(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStorageVersionListV1Alpha1Props",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeStorageVersionListV1Alpha1Props:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeStorageVersionV1Alpha1Props", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''A list of StorageVersions.

        :param items: Items holds a list of StorageVersion.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeStorageVersionV1Alpha1Props, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeStorageVersionV1Alpha1Props"]:
        '''Items holds a list of StorageVersion.

        :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeStorageVersionV1Alpha1Props"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersionList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStorageVersionListV1Alpha1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeStorageVersionV1Alpha1(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeStorageVersionV1Alpha1",
):
    '''Storage version of a specific resource.

    :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Any,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.apiserverinternal.v1alpha1.StorageVersion" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec is an empty spec. It is here to comply with Kubernetes API style.
        :param metadata: The name is ..
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Any,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeStorageVersionV1Alpha1Props(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Any,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.apiserverinternal.v1alpha1.StorageVersion".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec is an empty spec. It is here to comply with Kubernetes API style.
        :param metadata: The name is ..
        '''
        props = KubeStorageVersionV1Alpha1Props(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.apiserverinternal.v1alpha1.StorageVersion".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeStorageVersionV1Alpha1Props",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeStorageVersionV1Alpha1Props:
    def __init__(
        self,
        *,
        spec: typing.Any,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Storage version of a specific resource.

        :param spec: Spec is an empty spec. It is here to comply with Kubernetes API style.
        :param metadata: The name is ..

        :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Any,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> typing.Any:
        '''Spec is an empty spec.

        It is here to comply with Kubernetes API style.

        :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Any, result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''The name is ..

        :schema: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeStorageVersionV1Alpha1Props(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeSubjectAccessReview(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeSubjectAccessReview",
):
    '''SubjectAccessReview checks whether or not a user or group can perform an action.

    :schema: io.k8s.api.authorization.v1.SubjectAccessReview
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["SubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.authorization.v1.SubjectAccessReview" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[SubjectAccessReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeSubjectAccessReviewProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["SubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.authorization.v1.SubjectAccessReview".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeSubjectAccessReviewProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.authorization.v1.SubjectAccessReview".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeSubjectAccessReviewProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeSubjectAccessReviewProps:
    def __init__(
        self,
        *,
        spec: typing.Union["SubjectAccessReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SubjectAccessReview checks whether or not a user or group can perform an action.

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.SubjectAccessReview
        '''
        if isinstance(spec, dict):
            spec = SubjectAccessReviewSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[SubjectAccessReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "SubjectAccessReviewSpec":
        '''Spec holds information about the request being evaluated.

        :schema: io.k8s.api.authorization.v1.SubjectAccessReview#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("SubjectAccessReviewSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authorization.v1.SubjectAccessReview#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeSubjectAccessReviewProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeTokenRequest(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeTokenRequest",
):
    '''TokenRequest requests a token for a given service account.

    :schema: io.k8s.api.authentication.v1.TokenRequest
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["TokenRequestSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.authentication.v1.TokenRequest" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[TokenRequestSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeTokenRequestProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["TokenRequestSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.authentication.v1.TokenRequest".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeTokenRequestProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.authentication.v1.TokenRequest".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeTokenRequestProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeTokenRequestProps:
    def __init__(
        self,
        *,
        spec: typing.Union["TokenRequestSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''TokenRequest requests a token for a given service account.

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authentication.v1.TokenRequest
        '''
        if isinstance(spec, dict):
            spec = TokenRequestSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[TokenRequestSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "TokenRequestSpec":
        '''Spec holds information about the request being evaluated.

        :schema: io.k8s.api.authentication.v1.TokenRequest#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("TokenRequestSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authentication.v1.TokenRequest#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeTokenRequestProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeTokenReview(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeTokenReview",
):
    '''TokenReview attempts to authenticate a token to a known user.

    Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.

    :schema: io.k8s.api.authentication.v1.TokenReview
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["TokenReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.authentication.v1.TokenReview" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[TokenReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeTokenReviewProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["TokenReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.authentication.v1.TokenReview".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeTokenReviewProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.authentication.v1.TokenReview".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeTokenReviewProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeTokenReviewProps:
    def __init__(
        self,
        *,
        spec: typing.Union["TokenReviewSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''TokenReview attempts to authenticate a token to a known user.

        Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.

        :param spec: Spec holds information about the request being evaluated.
        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authentication.v1.TokenReview
        '''
        if isinstance(spec, dict):
            spec = TokenReviewSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[TokenReviewSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "TokenReviewSpec":
        '''Spec holds information about the request being evaluated.

        :schema: io.k8s.api.authentication.v1.TokenReview#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("TokenReviewSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.authentication.v1.TokenReview#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeTokenReviewProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeValidatingWebhookConfiguration(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeValidatingWebhookConfiguration",
):
    '''ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.

    :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        webhooks: typing.Optional[typing.Sequence[typing.Union["ValidatingWebhook", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param webhooks: Webhooks is a list of webhooks and the affected resources and operations.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                webhooks: typing.Optional[typing.Sequence[typing.Union[ValidatingWebhook, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeValidatingWebhookConfigurationProps(
            metadata=metadata, webhooks=webhooks
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        webhooks: typing.Optional[typing.Sequence[typing.Union["ValidatingWebhook", typing.Dict[str, typing.Any]]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param webhooks: Webhooks is a list of webhooks and the affected resources and operations.
        '''
        props = KubeValidatingWebhookConfigurationProps(
            metadata=metadata, webhooks=webhooks
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeValidatingWebhookConfigurationList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeValidatingWebhookConfigurationList",
):
    '''ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.

    :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeValidatingWebhookConfigurationProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: List of ValidatingWebhookConfiguration.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeValidatingWebhookConfigurationProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeValidatingWebhookConfigurationListProps(
            items=items, metadata=metadata
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeValidatingWebhookConfigurationProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: List of ValidatingWebhookConfiguration.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        '''
        props = KubeValidatingWebhookConfigurationListProps(
            items=items, metadata=metadata
        )

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeValidatingWebhookConfigurationListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeValidatingWebhookConfigurationListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeValidatingWebhookConfigurationProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.

        :param items: List of ValidatingWebhookConfiguration.
        :param metadata: Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeValidatingWebhookConfigurationProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeValidatingWebhookConfigurationProps"]:
        '''List of ValidatingWebhookConfiguration.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeValidatingWebhookConfigurationProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfigurationList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeValidatingWebhookConfigurationListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeValidatingWebhookConfigurationProps",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "webhooks": "webhooks"},
)
class KubeValidatingWebhookConfigurationProps:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
        webhooks: typing.Optional[typing.Sequence[typing.Union["ValidatingWebhook", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.

        :param metadata: Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        :param webhooks: Webhooks is a list of webhooks and the affected resources and operations.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                webhooks: typing.Optional[typing.Sequence[typing.Union[ValidatingWebhook, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument webhooks", value=webhooks, expected_type=type_hints["webhooks"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if webhooks is not None:
            self._values["webhooks"] = webhooks

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object metadata;

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    @builtins.property
    def webhooks(self) -> typing.Optional[typing.List["ValidatingWebhook"]]:
        '''Webhooks is a list of webhooks and the affected resources and operations.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhookConfiguration#webhooks
        '''
        result = self._values.get("webhooks")
        return typing.cast(typing.Optional[typing.List["ValidatingWebhook"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeValidatingWebhookConfigurationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class KubeVolumeAttachment(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeVolumeAttachment",
):
    '''VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.

    VolumeAttachment objects are non-namespaced.

    :schema: io.k8s.api.storage.v1.VolumeAttachment
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        spec: typing.Union["VolumeAttachmentSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.VolumeAttachment" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param spec: Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.
        :param metadata: Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                spec: typing.Union[VolumeAttachmentSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeVolumeAttachmentProps(spec=spec, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        spec: typing.Union["VolumeAttachmentSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.VolumeAttachment".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param spec: Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.
        :param metadata: Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        '''
        props = KubeVolumeAttachmentProps(spec=spec, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.VolumeAttachment".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


class KubeVolumeAttachmentList(
    cdk8s.ApiObject,
    metaclass=jsii.JSIIMeta,
    jsii_type="cdk8s-plus-23.k8s.KubeVolumeAttachmentList",
):
    '''VolumeAttachmentList is a collection of VolumeAttachment objects.

    :schema: io.k8s.api.storage.v1.VolumeAttachmentList
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[typing.Union["KubeVolumeAttachmentProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a "io.k8s.api.storage.v1.VolumeAttachmentList" API object.

        :param scope: the scope in which to define this object.
        :param id: a scope-local name for the object.
        :param items: Items is the list of VolumeAttachments.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        if __debug__:
            def stub(
                scope: constructs.Construct,
                id: builtins.str,
                *,
                items: typing.Sequence[typing.Union[KubeVolumeAttachmentProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = KubeVolumeAttachmentListProps(items=items, metadata=metadata)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="manifest")
    @builtins.classmethod
    def manifest(
        cls,
        *,
        items: typing.Sequence[typing.Union["KubeVolumeAttachmentProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> typing.Any:
        '''Renders a Kubernetes manifest for "io.k8s.api.storage.v1.VolumeAttachmentList".

        This can be used to inline resource manifests inside other objects (e.g. as templates).

        :param items: Items is the list of VolumeAttachments.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
        '''
        props = KubeVolumeAttachmentListProps(items=items, metadata=metadata)

        return typing.cast(typing.Any, jsii.sinvoke(cls, "manifest", [props]))

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        '''Renders the object to Kubernetes JSON.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toJson", []))

    @jsii.python.classproperty
    @jsii.member(jsii_name="GVK")
    def GVK(cls) -> cdk8s.GroupVersionKind:
        '''Returns the apiVersion and kind for "io.k8s.api.storage.v1.VolumeAttachmentList".'''
        return typing.cast(cdk8s.GroupVersionKind, jsii.sget(cls, "GVK"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeVolumeAttachmentListProps",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "metadata": "metadata"},
)
class KubeVolumeAttachmentListProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[typing.Union["KubeVolumeAttachmentProps", typing.Dict[str, typing.Any]]],
        metadata: typing.Optional[typing.Union["ListMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''VolumeAttachmentList is a collection of VolumeAttachment objects.

        :param items: Items is the list of VolumeAttachments.
        :param metadata: Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentList
        '''
        if isinstance(metadata, dict):
            metadata = ListMeta(**metadata)
        if __debug__:
            def stub(
                *,
                items: typing.Sequence[typing.Union[KubeVolumeAttachmentProps, typing.Dict[str, typing.Any]]],
                metadata: typing.Optional[typing.Union[ListMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def items(self) -> typing.List["KubeVolumeAttachmentProps"]:
        '''Items is the list of VolumeAttachments.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentList#items
        '''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List["KubeVolumeAttachmentProps"], result)

    @builtins.property
    def metadata(self) -> typing.Optional["ListMeta"]:
        '''Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentList#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ListMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeVolumeAttachmentListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.KubeVolumeAttachmentProps",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class KubeVolumeAttachmentProps:
    def __init__(
        self,
        *,
        spec: typing.Union["VolumeAttachmentSpec", typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union["ObjectMeta", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.

        VolumeAttachment objects are non-namespaced.

        :param spec: Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.
        :param metadata: Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1.VolumeAttachment
        '''
        if isinstance(spec, dict):
            spec = VolumeAttachmentSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[VolumeAttachmentSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> "VolumeAttachmentSpec":
        '''Specification of the desired attach/detach volume behavior.

        Populated by the Kubernetes system.

        :schema: io.k8s.api.storage.v1.VolumeAttachment#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast("VolumeAttachmentSpec", result)

    @builtins.property
    def metadata(self) -> typing.Optional["ObjectMeta"]:
        '''Standard object metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.storage.v1.VolumeAttachment#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional["ObjectMeta"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KubeVolumeAttachmentProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LabelSelector",
    jsii_struct_bases=[],
    name_mapping={
        "match_expressions": "matchExpressions",
        "match_labels": "matchLabels",
    },
)
class LabelSelector:
    def __init__(
        self,
        *,
        match_expressions: typing.Optional[typing.Sequence[typing.Union["LabelSelectorRequirement", typing.Dict[str, typing.Any]]]] = None,
        match_labels: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
    ) -> None:
        '''A label selector is a label query over a set of resources.

        The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.

        :param match_expressions: matchExpressions is a list of label selector requirements. The requirements are ANDed.
        :param match_labels: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector
        '''
        if __debug__:
            def stub(
                *,
                match_expressions: typing.Optional[typing.Sequence[typing.Union[LabelSelectorRequirement, typing.Dict[str, typing.Any]]]] = None,
                match_labels: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument match_expressions", value=match_expressions, expected_type=type_hints["match_expressions"])
            check_type(argname="argument match_labels", value=match_labels, expected_type=type_hints["match_labels"])
        self._values: typing.Dict[str, typing.Any] = {}
        if match_expressions is not None:
            self._values["match_expressions"] = match_expressions
        if match_labels is not None:
            self._values["match_labels"] = match_labels

    @builtins.property
    def match_expressions(
        self,
    ) -> typing.Optional[typing.List["LabelSelectorRequirement"]]:
        '''matchExpressions is a list of label selector requirements.

        The requirements are ANDed.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector#matchExpressions
        '''
        result = self._values.get("match_expressions")
        return typing.cast(typing.Optional[typing.List["LabelSelectorRequirement"]], result)

    @builtins.property
    def match_labels(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''matchLabels is a map of {key,value} pairs.

        A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector#matchLabels
        '''
        result = self._values.get("match_labels")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LabelSelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LabelSelectorRequirement",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "operator": "operator", "values": "values"},
)
class LabelSelectorRequirement:
    def __init__(
        self,
        *,
        key: builtins.str,
        operator: builtins.str,
        values: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

        :param key: key is the label key that the selector applies to.
        :param operator: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
        :param values: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement
        '''
        if __debug__:
            def stub(
                *,
                key: builtins.str,
                operator: builtins.str,
                values: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument operator", value=operator, expected_type=type_hints["operator"])
            check_type(argname="argument values", value=values, expected_type=type_hints["values"])
        self._values: typing.Dict[str, typing.Any] = {
            "key": key,
            "operator": operator,
        }
        if values is not None:
            self._values["values"] = values

    @builtins.property
    def key(self) -> builtins.str:
        '''key is the label key that the selector applies to.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def operator(self) -> builtins.str:
        '''operator represents a key's relationship to a set of values.

        Valid operators are In, NotIn, Exists and DoesNotExist.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement#operator
        '''
        result = self._values.get("operator")
        assert result is not None, "Required property 'operator' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def values(self) -> typing.Optional[typing.List[builtins.str]]:
        '''values is an array of string values.

        If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement#values
        '''
        result = self._values.get("values")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LabelSelectorRequirement(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LeaseSpec",
    jsii_struct_bases=[],
    name_mapping={
        "acquire_time": "acquireTime",
        "holder_identity": "holderIdentity",
        "lease_duration_seconds": "leaseDurationSeconds",
        "lease_transitions": "leaseTransitions",
        "renew_time": "renewTime",
    },
)
class LeaseSpec:
    def __init__(
        self,
        *,
        acquire_time: typing.Optional[datetime.datetime] = None,
        holder_identity: typing.Optional[builtins.str] = None,
        lease_duration_seconds: typing.Optional[jsii.Number] = None,
        lease_transitions: typing.Optional[jsii.Number] = None,
        renew_time: typing.Optional[datetime.datetime] = None,
    ) -> None:
        '''LeaseSpec is a specification of a Lease.

        :param acquire_time: acquireTime is a time when the current lease was acquired.
        :param holder_identity: holderIdentity contains the identity of the holder of a current lease.
        :param lease_duration_seconds: leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed RenewTime.
        :param lease_transitions: leaseTransitions is the number of transitions of a lease between holders.
        :param renew_time: renewTime is a time when the current holder of a lease has last updated the lease.

        :schema: io.k8s.api.coordination.v1.LeaseSpec
        '''
        if __debug__:
            def stub(
                *,
                acquire_time: typing.Optional[datetime.datetime] = None,
                holder_identity: typing.Optional[builtins.str] = None,
                lease_duration_seconds: typing.Optional[jsii.Number] = None,
                lease_transitions: typing.Optional[jsii.Number] = None,
                renew_time: typing.Optional[datetime.datetime] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument acquire_time", value=acquire_time, expected_type=type_hints["acquire_time"])
            check_type(argname="argument holder_identity", value=holder_identity, expected_type=type_hints["holder_identity"])
            check_type(argname="argument lease_duration_seconds", value=lease_duration_seconds, expected_type=type_hints["lease_duration_seconds"])
            check_type(argname="argument lease_transitions", value=lease_transitions, expected_type=type_hints["lease_transitions"])
            check_type(argname="argument renew_time", value=renew_time, expected_type=type_hints["renew_time"])
        self._values: typing.Dict[str, typing.Any] = {}
        if acquire_time is not None:
            self._values["acquire_time"] = acquire_time
        if holder_identity is not None:
            self._values["holder_identity"] = holder_identity
        if lease_duration_seconds is not None:
            self._values["lease_duration_seconds"] = lease_duration_seconds
        if lease_transitions is not None:
            self._values["lease_transitions"] = lease_transitions
        if renew_time is not None:
            self._values["renew_time"] = renew_time

    @builtins.property
    def acquire_time(self) -> typing.Optional[datetime.datetime]:
        '''acquireTime is a time when the current lease was acquired.

        :schema: io.k8s.api.coordination.v1.LeaseSpec#acquireTime
        '''
        result = self._values.get("acquire_time")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def holder_identity(self) -> typing.Optional[builtins.str]:
        '''holderIdentity contains the identity of the holder of a current lease.

        :schema: io.k8s.api.coordination.v1.LeaseSpec#holderIdentity
        '''
        result = self._values.get("holder_identity")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def lease_duration_seconds(self) -> typing.Optional[jsii.Number]:
        '''leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it.

        This is measure against time of last observed RenewTime.

        :schema: io.k8s.api.coordination.v1.LeaseSpec#leaseDurationSeconds
        '''
        result = self._values.get("lease_duration_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def lease_transitions(self) -> typing.Optional[jsii.Number]:
        '''leaseTransitions is the number of transitions of a lease between holders.

        :schema: io.k8s.api.coordination.v1.LeaseSpec#leaseTransitions
        '''
        result = self._values.get("lease_transitions")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def renew_time(self) -> typing.Optional[datetime.datetime]:
        '''renewTime is a time when the current holder of a lease has last updated the lease.

        :schema: io.k8s.api.coordination.v1.LeaseSpec#renewTime
        '''
        result = self._values.get("renew_time")
        return typing.cast(typing.Optional[datetime.datetime], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LeaseSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Lifecycle",
    jsii_struct_bases=[],
    name_mapping={"post_start": "postStart", "pre_stop": "preStop"},
)
class Lifecycle:
    def __init__(
        self,
        *,
        post_start: typing.Optional[typing.Union["LifecycleHandler", typing.Dict[str, typing.Any]]] = None,
        pre_stop: typing.Optional[typing.Union["LifecycleHandler", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Lifecycle describes actions that the management system should take in response to container lifecycle events.

        For the PostStart and PreStop lifecycle handlers, management of the container blocks until the action is complete, unless the container process fails, in which case the handler is aborted.

        :param post_start: PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
        :param pre_stop: PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod's termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod's termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

        :schema: io.k8s.api.core.v1.Lifecycle
        '''
        if isinstance(post_start, dict):
            post_start = LifecycleHandler(**post_start)
        if isinstance(pre_stop, dict):
            pre_stop = LifecycleHandler(**pre_stop)
        if __debug__:
            def stub(
                *,
                post_start: typing.Optional[typing.Union[LifecycleHandler, typing.Dict[str, typing.Any]]] = None,
                pre_stop: typing.Optional[typing.Union[LifecycleHandler, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument post_start", value=post_start, expected_type=type_hints["post_start"])
            check_type(argname="argument pre_stop", value=pre_stop, expected_type=type_hints["pre_stop"])
        self._values: typing.Dict[str, typing.Any] = {}
        if post_start is not None:
            self._values["post_start"] = post_start
        if pre_stop is not None:
            self._values["pre_stop"] = pre_stop

    @builtins.property
    def post_start(self) -> typing.Optional["LifecycleHandler"]:
        '''PostStart is called immediately after a container is created.

        If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

        :schema: io.k8s.api.core.v1.Lifecycle#postStart
        '''
        result = self._values.get("post_start")
        return typing.cast(typing.Optional["LifecycleHandler"], result)

    @builtins.property
    def pre_stop(self) -> typing.Optional["LifecycleHandler"]:
        '''PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc.

        The handler is not called if the container crashes or exits. The Pod's termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod's termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

        :schema: io.k8s.api.core.v1.Lifecycle#preStop
        '''
        result = self._values.get("pre_stop")
        return typing.cast(typing.Optional["LifecycleHandler"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Lifecycle(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LifecycleHandler",
    jsii_struct_bases=[],
    name_mapping={"exec": "exec", "http_get": "httpGet", "tcp_socket": "tcpSocket"},
)
class LifecycleHandler:
    def __init__(
        self,
        *,
        exec: typing.Optional[typing.Union[ExecAction, typing.Dict[str, typing.Any]]] = None,
        http_get: typing.Optional[typing.Union[HttpGetAction, typing.Dict[str, typing.Any]]] = None,
        tcp_socket: typing.Optional[typing.Union["TcpSocketAction", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LifecycleHandler defines a specific action that should be taken in a lifecycle hook.

        One and only one of the fields, except TCPSocket must be specified.

        :param exec: Exec specifies the action to take.
        :param http_get: HTTPGet specifies the http request to perform.
        :param tcp_socket: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified.

        :schema: io.k8s.api.core.v1.LifecycleHandler
        '''
        if isinstance(exec, dict):
            exec = ExecAction(**exec)
        if isinstance(http_get, dict):
            http_get = HttpGetAction(**http_get)
        if isinstance(tcp_socket, dict):
            tcp_socket = TcpSocketAction(**tcp_socket)
        if __debug__:
            def stub(
                *,
                exec: typing.Optional[typing.Union[ExecAction, typing.Dict[str, typing.Any]]] = None,
                http_get: typing.Optional[typing.Union[HttpGetAction, typing.Dict[str, typing.Any]]] = None,
                tcp_socket: typing.Optional[typing.Union[TcpSocketAction, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument exec", value=exec, expected_type=type_hints["exec"])
            check_type(argname="argument http_get", value=http_get, expected_type=type_hints["http_get"])
            check_type(argname="argument tcp_socket", value=tcp_socket, expected_type=type_hints["tcp_socket"])
        self._values: typing.Dict[str, typing.Any] = {}
        if exec is not None:
            self._values["exec"] = exec
        if http_get is not None:
            self._values["http_get"] = http_get
        if tcp_socket is not None:
            self._values["tcp_socket"] = tcp_socket

    @builtins.property
    def exec(self) -> typing.Optional[ExecAction]:
        '''Exec specifies the action to take.

        :schema: io.k8s.api.core.v1.LifecycleHandler#exec
        '''
        result = self._values.get("exec")
        return typing.cast(typing.Optional[ExecAction], result)

    @builtins.property
    def http_get(self) -> typing.Optional[HttpGetAction]:
        '''HTTPGet specifies the http request to perform.

        :schema: io.k8s.api.core.v1.LifecycleHandler#httpGet
        '''
        result = self._values.get("http_get")
        return typing.cast(typing.Optional[HttpGetAction], result)

    @builtins.property
    def tcp_socket(self) -> typing.Optional["TcpSocketAction"]:
        '''Deprecated.

        TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified.

        :schema: io.k8s.api.core.v1.LifecycleHandler#tcpSocket
        '''
        result = self._values.get("tcp_socket")
        return typing.cast(typing.Optional["TcpSocketAction"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LifecycleHandler(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LimitRangeItem",
    jsii_struct_bases=[],
    name_mapping={
        "type": "type",
        "default": "default",
        "default_request": "defaultRequest",
        "max": "max",
        "max_limit_request_ratio": "maxLimitRequestRatio",
        "min": "min",
    },
)
class LimitRangeItem:
    def __init__(
        self,
        *,
        type: IoK8SApiCoreV1LimitRangeItemType,
        default: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
        default_request: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
        max: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
        max_limit_request_ratio: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
        min: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
    ) -> None:
        '''LimitRangeItem defines a min/max usage limit for any resource that matches on kind.

        :param type: Type of resource that this limit applies to. Possible enum values: - ``"Container"`` Limit that applies to all containers in a namespace - ``"PersistentVolumeClaim"`` Limit that applies to all persistent volume claims in a namespace - ``"Pod"`` Limit that applies to all pods in a namespace
        :param default: Default resource requirement limit value by resource name if resource limit is omitted.
        :param default_request: DefaultRequest is the default resource requirement request value by resource name if resource request is omitted.
        :param max: Max usage constraints on this kind by resource name.
        :param max_limit_request_ratio: MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource.
        :param min: Min usage constraints on this kind by resource name.

        :schema: io.k8s.api.core.v1.LimitRangeItem
        '''
        if __debug__:
            def stub(
                *,
                type: IoK8SApiCoreV1LimitRangeItemType,
                default: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                default_request: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                max: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                max_limit_request_ratio: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                min: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument default", value=default, expected_type=type_hints["default"])
            check_type(argname="argument default_request", value=default_request, expected_type=type_hints["default_request"])
            check_type(argname="argument max", value=max, expected_type=type_hints["max"])
            check_type(argname="argument max_limit_request_ratio", value=max_limit_request_ratio, expected_type=type_hints["max_limit_request_ratio"])
            check_type(argname="argument min", value=min, expected_type=type_hints["min"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if default is not None:
            self._values["default"] = default
        if default_request is not None:
            self._values["default_request"] = default_request
        if max is not None:
            self._values["max"] = max
        if max_limit_request_ratio is not None:
            self._values["max_limit_request_ratio"] = max_limit_request_ratio
        if min is not None:
            self._values["min"] = min

    @builtins.property
    def type(self) -> IoK8SApiCoreV1LimitRangeItemType:
        '''Type of resource that this limit applies to.

        Possible enum values:

        - ``"Container"`` Limit that applies to all containers in a namespace
        - ``"PersistentVolumeClaim"`` Limit that applies to all persistent volume claims in a namespace
        - ``"Pod"`` Limit that applies to all pods in a namespace

        :schema: io.k8s.api.core.v1.LimitRangeItem#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(IoK8SApiCoreV1LimitRangeItemType, result)

    @builtins.property
    def default(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''Default resource requirement limit value by resource name if resource limit is omitted.

        :schema: io.k8s.api.core.v1.LimitRangeItem#default
        '''
        result = self._values.get("default")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    @builtins.property
    def default_request(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''DefaultRequest is the default resource requirement request value by resource name if resource request is omitted.

        :schema: io.k8s.api.core.v1.LimitRangeItem#defaultRequest
        '''
        result = self._values.get("default_request")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    @builtins.property
    def max(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''Max usage constraints on this kind by resource name.

        :schema: io.k8s.api.core.v1.LimitRangeItem#max
        '''
        result = self._values.get("max")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    @builtins.property
    def max_limit_request_ratio(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value;

        this represents the max burst for the named resource.

        :schema: io.k8s.api.core.v1.LimitRangeItem#maxLimitRequestRatio
        '''
        result = self._values.get("max_limit_request_ratio")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    @builtins.property
    def min(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''Min usage constraints on this kind by resource name.

        :schema: io.k8s.api.core.v1.LimitRangeItem#min
        '''
        result = self._values.get("min")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LimitRangeItem(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LimitRangeSpec",
    jsii_struct_bases=[],
    name_mapping={"limits": "limits"},
)
class LimitRangeSpec:
    def __init__(
        self,
        *,
        limits: typing.Sequence[typing.Union[LimitRangeItem, typing.Dict[str, typing.Any]]],
    ) -> None:
        '''LimitRangeSpec defines a min/max usage limit for resources that match on kind.

        :param limits: Limits is the list of LimitRangeItem objects that are enforced.

        :schema: io.k8s.api.core.v1.LimitRangeSpec
        '''
        if __debug__:
            def stub(
                *,
                limits: typing.Sequence[typing.Union[LimitRangeItem, typing.Dict[str, typing.Any]]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument limits", value=limits, expected_type=type_hints["limits"])
        self._values: typing.Dict[str, typing.Any] = {
            "limits": limits,
        }

    @builtins.property
    def limits(self) -> typing.List[LimitRangeItem]:
        '''Limits is the list of LimitRangeItem objects that are enforced.

        :schema: io.k8s.api.core.v1.LimitRangeSpec#limits
        '''
        result = self._values.get("limits")
        assert result is not None, "Required property 'limits' is missing"
        return typing.cast(typing.List[LimitRangeItem], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LimitRangeSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LimitResponseV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "queuing": "queuing"},
)
class LimitResponseV1Beta1:
    def __init__(
        self,
        *,
        type: builtins.str,
        queuing: typing.Optional[typing.Union["QueuingConfigurationV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LimitResponse defines how to handle requests that can not be executed right now.

        :param type: ``type`` is "Queue" or "Reject". "Queue" means that requests that can not be executed upon arrival are held in a queue until they can be executed or a queuing limit is reached. "Reject" means that requests that can not be executed upon arrival are rejected. Required.
        :param queuing: ``queuing`` holds the configuration parameters for queuing. This field may be non-empty only if ``type`` is ``"Queue"``.

        :schema: io.k8s.api.flowcontrol.v1beta1.LimitResponse
        '''
        if isinstance(queuing, dict):
            queuing = QueuingConfigurationV1Beta1(**queuing)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                queuing: typing.Optional[typing.Union[QueuingConfigurationV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument queuing", value=queuing, expected_type=type_hints["queuing"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if queuing is not None:
            self._values["queuing"] = queuing

    @builtins.property
    def type(self) -> builtins.str:
        '''``type`` is "Queue" or "Reject".

        "Queue" means that requests that can not be executed upon arrival are held in a queue until they can be executed or a queuing limit is reached. "Reject" means that requests that can not be executed upon arrival are rejected. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.LimitResponse#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def queuing(self) -> typing.Optional["QueuingConfigurationV1Beta1"]:
        '''``queuing`` holds the configuration parameters for queuing.

        This field may be non-empty only if ``type`` is ``"Queue"``.

        :schema: io.k8s.api.flowcontrol.v1beta1.LimitResponse#queuing
        '''
        result = self._values.get("queuing")
        return typing.cast(typing.Optional["QueuingConfigurationV1Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LimitResponseV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LimitResponseV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "queuing": "queuing"},
)
class LimitResponseV1Beta2:
    def __init__(
        self,
        *,
        type: builtins.str,
        queuing: typing.Optional[typing.Union["QueuingConfigurationV1Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LimitResponse defines how to handle requests that can not be executed right now.

        :param type: ``type`` is "Queue" or "Reject". "Queue" means that requests that can not be executed upon arrival are held in a queue until they can be executed or a queuing limit is reached. "Reject" means that requests that can not be executed upon arrival are rejected. Required.
        :param queuing: ``queuing`` holds the configuration parameters for queuing. This field may be non-empty only if ``type`` is ``"Queue"``.

        :schema: io.k8s.api.flowcontrol.v1beta2.LimitResponse
        '''
        if isinstance(queuing, dict):
            queuing = QueuingConfigurationV1Beta2(**queuing)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                queuing: typing.Optional[typing.Union[QueuingConfigurationV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument queuing", value=queuing, expected_type=type_hints["queuing"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if queuing is not None:
            self._values["queuing"] = queuing

    @builtins.property
    def type(self) -> builtins.str:
        '''``type`` is "Queue" or "Reject".

        "Queue" means that requests that can not be executed upon arrival are held in a queue until they can be executed or a queuing limit is reached. "Reject" means that requests that can not be executed upon arrival are rejected. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.LimitResponse#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def queuing(self) -> typing.Optional["QueuingConfigurationV1Beta2"]:
        '''``queuing`` holds the configuration parameters for queuing.

        This field may be non-empty only if ``type`` is ``"Queue"``.

        :schema: io.k8s.api.flowcontrol.v1beta2.LimitResponse#queuing
        '''
        result = self._values.get("queuing")
        return typing.cast(typing.Optional["QueuingConfigurationV1Beta2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LimitResponseV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LimitedPriorityLevelConfigurationV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "assured_concurrency_shares": "assuredConcurrencyShares",
        "limit_response": "limitResponse",
    },
)
class LimitedPriorityLevelConfigurationV1Beta1:
    def __init__(
        self,
        *,
        assured_concurrency_shares: typing.Optional[jsii.Number] = None,
        limit_response: typing.Optional[typing.Union[LimitResponseV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits.

        It addresses two issues:

        - How are requests for this priority level limited?
        - What should be done with requests that exceed the limit?

        :param assured_concurrency_shares: ``assuredConcurrencyShares`` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) --- the number of requests that may be executing at a time --- for each such priority level: ACV(l) = ceil( SCL * ACS(l) / ( sum[priority levels k] ACS(k) ) ) bigger numbers of ACS mean more reserved concurrent requests (at the expense of every other PL). This field has a default value of 30.
        :param limit_response: ``limitResponse`` indicates what to do with requests that can not be executed right now.

        :schema: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration
        '''
        if isinstance(limit_response, dict):
            limit_response = LimitResponseV1Beta1(**limit_response)
        if __debug__:
            def stub(
                *,
                assured_concurrency_shares: typing.Optional[jsii.Number] = None,
                limit_response: typing.Optional[typing.Union[LimitResponseV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument assured_concurrency_shares", value=assured_concurrency_shares, expected_type=type_hints["assured_concurrency_shares"])
            check_type(argname="argument limit_response", value=limit_response, expected_type=type_hints["limit_response"])
        self._values: typing.Dict[str, typing.Any] = {}
        if assured_concurrency_shares is not None:
            self._values["assured_concurrency_shares"] = assured_concurrency_shares
        if limit_response is not None:
            self._values["limit_response"] = limit_response

    @builtins.property
    def assured_concurrency_shares(self) -> typing.Optional[jsii.Number]:
        '''``assuredConcurrencyShares`` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time.

        ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) --- the number of requests that may be executing at a time --- for each such priority level:

        ACV(l) = ceil( SCL * ACS(l) / ( sum[priority levels k] ACS(k) ) )

        bigger numbers of ACS mean more reserved concurrent requests (at the expense of every other PL). This field has a default value of 30.

        :schema: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration#assuredConcurrencyShares
        '''
        result = self._values.get("assured_concurrency_shares")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def limit_response(self) -> typing.Optional[LimitResponseV1Beta1]:
        '''``limitResponse`` indicates what to do with requests that can not be executed right now.

        :schema: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration#limitResponse
        '''
        result = self._values.get("limit_response")
        return typing.cast(typing.Optional[LimitResponseV1Beta1], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LimitedPriorityLevelConfigurationV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LimitedPriorityLevelConfigurationV1Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "assured_concurrency_shares": "assuredConcurrencyShares",
        "limit_response": "limitResponse",
    },
)
class LimitedPriorityLevelConfigurationV1Beta2:
    def __init__(
        self,
        *,
        assured_concurrency_shares: typing.Optional[jsii.Number] = None,
        limit_response: typing.Optional[typing.Union[LimitResponseV1Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits.

        It addresses two issues:

        - How are requests for this priority level limited?
        - What should be done with requests that exceed the limit?

        :param assured_concurrency_shares: ``assuredConcurrencyShares`` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) --- the number of requests that may be executing at a time --- for each such priority level: ACV(l) = ceil( SCL * ACS(l) / ( sum[priority levels k] ACS(k) ) ) bigger numbers of ACS mean more reserved concurrent requests (at the expense of every other PL). This field has a default value of 30.
        :param limit_response: ``limitResponse`` indicates what to do with requests that can not be executed right now.

        :schema: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration
        '''
        if isinstance(limit_response, dict):
            limit_response = LimitResponseV1Beta2(**limit_response)
        if __debug__:
            def stub(
                *,
                assured_concurrency_shares: typing.Optional[jsii.Number] = None,
                limit_response: typing.Optional[typing.Union[LimitResponseV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument assured_concurrency_shares", value=assured_concurrency_shares, expected_type=type_hints["assured_concurrency_shares"])
            check_type(argname="argument limit_response", value=limit_response, expected_type=type_hints["limit_response"])
        self._values: typing.Dict[str, typing.Any] = {}
        if assured_concurrency_shares is not None:
            self._values["assured_concurrency_shares"] = assured_concurrency_shares
        if limit_response is not None:
            self._values["limit_response"] = limit_response

    @builtins.property
    def assured_concurrency_shares(self) -> typing.Optional[jsii.Number]:
        '''``assuredConcurrencyShares`` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time.

        ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) --- the number of requests that may be executing at a time --- for each such priority level:

        ACV(l) = ceil( SCL * ACS(l) / ( sum[priority levels k] ACS(k) ) )

        bigger numbers of ACS mean more reserved concurrent requests (at the expense of every other PL). This field has a default value of 30.

        :schema: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration#assuredConcurrencyShares
        '''
        result = self._values.get("assured_concurrency_shares")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def limit_response(self) -> typing.Optional[LimitResponseV1Beta2]:
        '''``limitResponse`` indicates what to do with requests that can not be executed right now.

        :schema: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration#limitResponse
        '''
        result = self._values.get("limit_response")
        return typing.cast(typing.Optional[LimitResponseV1Beta2], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LimitedPriorityLevelConfigurationV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ListMeta",
    jsii_struct_bases=[],
    name_mapping={
        "continue_": "continue",
        "remaining_item_count": "remainingItemCount",
        "resource_version": "resourceVersion",
        "self_link": "selfLink",
    },
)
class ListMeta:
    def __init__(
        self,
        *,
        continue_: typing.Optional[builtins.str] = None,
        remaining_item_count: typing.Optional[jsii.Number] = None,
        resource_version: typing.Optional[builtins.str] = None,
        self_link: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ListMeta describes metadata that synthetic resources must have, including lists and various status objects.

        A resource may have only one of {ObjectMeta, ListMeta}.

        :param continue_: continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.
        :param remaining_item_count: remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.
        :param resource_version: String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
        :param self_link: selfLink is a URL representing this object. Populated by the system. Read-only. DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta
        '''
        if __debug__:
            def stub(
                *,
                continue_: typing.Optional[builtins.str] = None,
                remaining_item_count: typing.Optional[jsii.Number] = None,
                resource_version: typing.Optional[builtins.str] = None,
                self_link: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument continue_", value=continue_, expected_type=type_hints["continue_"])
            check_type(argname="argument remaining_item_count", value=remaining_item_count, expected_type=type_hints["remaining_item_count"])
            check_type(argname="argument resource_version", value=resource_version, expected_type=type_hints["resource_version"])
            check_type(argname="argument self_link", value=self_link, expected_type=type_hints["self_link"])
        self._values: typing.Dict[str, typing.Any] = {}
        if continue_ is not None:
            self._values["continue_"] = continue_
        if remaining_item_count is not None:
            self._values["remaining_item_count"] = remaining_item_count
        if resource_version is not None:
            self._values["resource_version"] = resource_version
        if self_link is not None:
            self._values["self_link"] = self_link

    @builtins.property
    def continue_(self) -> typing.Optional[builtins.str]:
        '''continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available.

        The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta#continue
        '''
        result = self._values.get("continue_")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def remaining_item_count(self) -> typing.Optional[jsii.Number]:
        '''remainingItemCount is the number of subsequent items in the list which are not included in this list response.

        If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta#remainingItemCount
        '''
        result = self._values.get("remaining_item_count")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def resource_version(self) -> typing.Optional[builtins.str]:
        '''String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed.

        Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta#resourceVersion
        '''
        result = self._values.get("resource_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def self_link(self) -> typing.Optional[builtins.str]:
        '''selfLink is a URL representing this object. Populated by the system. Read-only.

        DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta#selfLink
        '''
        result = self._values.get("self_link")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ListMeta(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LocalObjectReference",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class LocalObjectReference:
    def __init__(self, *, name: typing.Optional[builtins.str] = None) -> None:
        '''LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace.

        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.LocalObjectReference
        '''
        if __debug__:
            def stub(*, name: typing.Optional[builtins.str] = None) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if name is not None:
            self._values["name"] = name

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.LocalObjectReference#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LocalObjectReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.LocalVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"path": "path", "fs_type": "fsType"},
)
class LocalVolumeSource:
    def __init__(
        self,
        *,
        path: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Local represents directly-attached storage with node affinity (Beta feature).

        :param path: The full path to the volume on the node. It can be either a directory or block device (disk, partition, ...).
        :param fs_type: Filesystem type to mount. It applies only when the Path is a block device. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default value is to auto-select a filesystem if unspecified.

        :schema: io.k8s.api.core.v1.LocalVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                path: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
        self._values: typing.Dict[str, typing.Any] = {
            "path": path,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type

    @builtins.property
    def path(self) -> builtins.str:
        '''The full path to the volume on the node.

        It can be either a directory or block device (disk, partition, ...).

        :schema: io.k8s.api.core.v1.LocalVolumeSource#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        It applies only when the Path is a block device. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default value is to auto-select a filesystem if unspecified.

        :schema: io.k8s.api.core.v1.LocalVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LocalVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ManagedFieldsEntry",
    jsii_struct_bases=[],
    name_mapping={
        "api_version": "apiVersion",
        "fields_type": "fieldsType",
        "fields_v1": "fieldsV1",
        "manager": "manager",
        "operation": "operation",
        "subresource": "subresource",
        "time": "time",
    },
)
class ManagedFieldsEntry:
    def __init__(
        self,
        *,
        api_version: typing.Optional[builtins.str] = None,
        fields_type: typing.Optional[builtins.str] = None,
        fields_v1: typing.Any = None,
        manager: typing.Optional[builtins.str] = None,
        operation: typing.Optional[builtins.str] = None,
        subresource: typing.Optional[builtins.str] = None,
        time: typing.Optional[datetime.datetime] = None,
    ) -> None:
        '''ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.

        :param api_version: APIVersion defines the version of this resource that this field set applies to. The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.
        :param fields_type: FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: "FieldsV1"
        :param fields_v1: FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.
        :param manager: Manager is an identifier of the workflow managing these fields.
        :param operation: Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.
        :param subresource: Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.
        :param time: Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry
        '''
        if __debug__:
            def stub(
                *,
                api_version: typing.Optional[builtins.str] = None,
                fields_type: typing.Optional[builtins.str] = None,
                fields_v1: typing.Any = None,
                manager: typing.Optional[builtins.str] = None,
                operation: typing.Optional[builtins.str] = None,
                subresource: typing.Optional[builtins.str] = None,
                time: typing.Optional[datetime.datetime] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
            check_type(argname="argument fields_type", value=fields_type, expected_type=type_hints["fields_type"])
            check_type(argname="argument fields_v1", value=fields_v1, expected_type=type_hints["fields_v1"])
            check_type(argname="argument manager", value=manager, expected_type=type_hints["manager"])
            check_type(argname="argument operation", value=operation, expected_type=type_hints["operation"])
            check_type(argname="argument subresource", value=subresource, expected_type=type_hints["subresource"])
            check_type(argname="argument time", value=time, expected_type=type_hints["time"])
        self._values: typing.Dict[str, typing.Any] = {}
        if api_version is not None:
            self._values["api_version"] = api_version
        if fields_type is not None:
            self._values["fields_type"] = fields_type
        if fields_v1 is not None:
            self._values["fields_v1"] = fields_v1
        if manager is not None:
            self._values["manager"] = manager
        if operation is not None:
            self._values["operation"] = operation
        if subresource is not None:
            self._values["subresource"] = subresource
        if time is not None:
            self._values["time"] = time

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''APIVersion defines the version of this resource that this field set applies to.

        The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def fields_type(self) -> typing.Optional[builtins.str]:
        '''FieldsType is the discriminator for the different fields format and version.

        There is currently only one possible value: "FieldsV1"

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#fieldsType
        '''
        result = self._values.get("fields_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def fields_v1(self) -> typing.Any:
        '''FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#fieldsV1
        '''
        result = self._values.get("fields_v1")
        return typing.cast(typing.Any, result)

    @builtins.property
    def manager(self) -> typing.Optional[builtins.str]:
        '''Manager is an identifier of the workflow managing these fields.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#manager
        '''
        result = self._values.get("manager")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def operation(self) -> typing.Optional[builtins.str]:
        '''Operation is the type of operation which lead to this ManagedFieldsEntry being created.

        The only valid values for this field are 'Apply' and 'Update'.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#operation
        '''
        result = self._values.get("operation")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subresource(self) -> typing.Optional[builtins.str]:
        '''Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource.

        The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#subresource
        '''
        result = self._values.get("subresource")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def time(self) -> typing.Optional[datetime.datetime]:
        '''Time is timestamp of when these fields were set.

        It should always be empty if Operation is 'Apply'

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry#time
        '''
        result = self._values.get("time")
        return typing.cast(typing.Optional[datetime.datetime], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ManagedFieldsEntry(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricIdentifierV2",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "selector": "selector"},
)
class MetricIdentifierV2:
    def __init__(
        self,
        *,
        name: builtins.str,
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''MetricIdentifier defines the name and optionally selector for a metric.

        :param name: name is the name of the given metric.
        :param selector: 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.

        :schema: io.k8s.api.autoscaling.v2.MetricIdentifier
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if selector is not None:
            self._values["selector"] = selector

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the given metric.

        :schema: io.k8s.api.autoscaling.v2.MetricIdentifier#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.MetricIdentifier#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricIdentifierV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricIdentifierV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "selector": "selector"},
)
class MetricIdentifierV2Beta2:
    def __init__(
        self,
        *,
        name: builtins.str,
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''MetricIdentifier defines the name and optionally selector for a metric.

        :param name: name is the name of the given metric.
        :param selector: 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.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricIdentifier
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if selector is not None:
            self._values["selector"] = selector

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricIdentifier#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricIdentifier#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricIdentifierV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricSpecV2",
    jsii_struct_bases=[],
    name_mapping={
        "type": "type",
        "container_resource": "containerResource",
        "external": "external",
        "object": "object",
        "pods": "pods",
        "resource": "resource",
    },
)
class MetricSpecV2:
    def __init__(
        self,
        *,
        type: builtins.str,
        container_resource: typing.Optional[typing.Union[ContainerResourceMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
        external: typing.Optional[typing.Union[ExternalMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
        object: typing.Optional[typing.Union["ObjectMetricSourceV2", typing.Dict[str, typing.Any]]] = None,
        pods: typing.Optional[typing.Union["PodsMetricSourceV2", typing.Dict[str, typing.Any]]] = None,
        resource: typing.Optional[typing.Union["ResourceMetricSourceV2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''MetricSpec specifies how to scale based on a single metric (only ``type`` and one other matching field should be set at once).

        :param type: 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
        :param container_resource: 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.
        :param external: 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).
        :param object: object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).
        :param pods: 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.
        :param resource: 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.

        :schema: io.k8s.api.autoscaling.v2.MetricSpec
        '''
        if isinstance(container_resource, dict):
            container_resource = ContainerResourceMetricSourceV2(**container_resource)
        if isinstance(external, dict):
            external = ExternalMetricSourceV2(**external)
        if isinstance(object, dict):
            object = ObjectMetricSourceV2(**object)
        if isinstance(pods, dict):
            pods = PodsMetricSourceV2(**pods)
        if isinstance(resource, dict):
            resource = ResourceMetricSourceV2(**resource)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                container_resource: typing.Optional[typing.Union[ContainerResourceMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
                external: typing.Optional[typing.Union[ExternalMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
                object: typing.Optional[typing.Union[ObjectMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
                pods: typing.Optional[typing.Union[PodsMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
                resource: typing.Optional[typing.Union[ResourceMetricSourceV2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument container_resource", value=container_resource, expected_type=type_hints["container_resource"])
            check_type(argname="argument external", value=external, expected_type=type_hints["external"])
            check_type(argname="argument object", value=object, expected_type=type_hints["object"])
            check_type(argname="argument pods", value=pods, expected_type=type_hints["pods"])
            check_type(argname="argument resource", value=resource, expected_type=type_hints["resource"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if container_resource is not None:
            self._values["container_resource"] = container_resource
        if external is not None:
            self._values["external"] = external
        if object is not None:
            self._values["object"] = object
        if pods is not None:
            self._values["pods"] = pods
        if resource is not None:
            self._values["resource"] = resource

    @builtins.property
    def type(self) -> builtins.str:
        '''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

        :schema: io.k8s.api.autoscaling.v2.MetricSpec#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def container_resource(self) -> typing.Optional[ContainerResourceMetricSourceV2]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.MetricSpec#containerResource
        '''
        result = self._values.get("container_resource")
        return typing.cast(typing.Optional[ContainerResourceMetricSourceV2], result)

    @builtins.property
    def external(self) -> typing.Optional[ExternalMetricSourceV2]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2.MetricSpec#external
        '''
        result = self._values.get("external")
        return typing.cast(typing.Optional[ExternalMetricSourceV2], result)

    @builtins.property
    def object(self) -> typing.Optional["ObjectMetricSourceV2"]:
        '''object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).

        :schema: io.k8s.api.autoscaling.v2.MetricSpec#object
        '''
        result = self._values.get("object")
        return typing.cast(typing.Optional["ObjectMetricSourceV2"], result)

    @builtins.property
    def pods(self) -> typing.Optional["PodsMetricSourceV2"]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.MetricSpec#pods
        '''
        result = self._values.get("pods")
        return typing.cast(typing.Optional["PodsMetricSourceV2"], result)

    @builtins.property
    def resource(self) -> typing.Optional["ResourceMetricSourceV2"]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2.MetricSpec#resource
        '''
        result = self._values.get("resource")
        return typing.cast(typing.Optional["ResourceMetricSourceV2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricSpecV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricSpecV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "type": "type",
        "container_resource": "containerResource",
        "external": "external",
        "object": "object",
        "pods": "pods",
        "resource": "resource",
    },
)
class MetricSpecV2Beta1:
    def __init__(
        self,
        *,
        type: builtins.str,
        container_resource: typing.Optional[typing.Union[ContainerResourceMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
        external: typing.Optional[typing.Union[ExternalMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
        object: typing.Optional[typing.Union["ObjectMetricSourceV2Beta1", typing.Dict[str, typing.Any]]] = None,
        pods: typing.Optional[typing.Union["PodsMetricSourceV2Beta1", typing.Dict[str, typing.Any]]] = None,
        resource: typing.Optional[typing.Union["ResourceMetricSourceV2Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''MetricSpec specifies how to scale based on a single metric (only ``type`` and one other matching field should be set at once).

        :param type: 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
        :param container_resource: 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 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.
        :param external: 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).
        :param object: object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).
        :param pods: 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.
        :param resource: 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.

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec
        '''
        if isinstance(container_resource, dict):
            container_resource = ContainerResourceMetricSourceV2Beta1(**container_resource)
        if isinstance(external, dict):
            external = ExternalMetricSourceV2Beta1(**external)
        if isinstance(object, dict):
            object = ObjectMetricSourceV2Beta1(**object)
        if isinstance(pods, dict):
            pods = PodsMetricSourceV2Beta1(**pods)
        if isinstance(resource, dict):
            resource = ResourceMetricSourceV2Beta1(**resource)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                container_resource: typing.Optional[typing.Union[ContainerResourceMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
                external: typing.Optional[typing.Union[ExternalMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
                object: typing.Optional[typing.Union[ObjectMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
                pods: typing.Optional[typing.Union[PodsMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
                resource: typing.Optional[typing.Union[ResourceMetricSourceV2Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument container_resource", value=container_resource, expected_type=type_hints["container_resource"])
            check_type(argname="argument external", value=external, expected_type=type_hints["external"])
            check_type(argname="argument object", value=object, expected_type=type_hints["object"])
            check_type(argname="argument pods", value=pods, expected_type=type_hints["pods"])
            check_type(argname="argument resource", value=resource, expected_type=type_hints["resource"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if container_resource is not None:
            self._values["container_resource"] = container_resource
        if external is not None:
            self._values["external"] = external
        if object is not None:
            self._values["object"] = object
        if pods is not None:
            self._values["pods"] = pods
        if resource is not None:
            self._values["resource"] = resource

    @builtins.property
    def type(self) -> builtins.str:
        '''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

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def container_resource(
        self,
    ) -> typing.Optional[ContainerResourceMetricSourceV2Beta1]:
        '''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 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.

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec#containerResource
        '''
        result = self._values.get("container_resource")
        return typing.cast(typing.Optional[ContainerResourceMetricSourceV2Beta1], result)

    @builtins.property
    def external(self) -> typing.Optional[ExternalMetricSourceV2Beta1]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec#external
        '''
        result = self._values.get("external")
        return typing.cast(typing.Optional[ExternalMetricSourceV2Beta1], result)

    @builtins.property
    def object(self) -> typing.Optional["ObjectMetricSourceV2Beta1"]:
        '''object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec#object
        '''
        result = self._values.get("object")
        return typing.cast(typing.Optional["ObjectMetricSourceV2Beta1"], result)

    @builtins.property
    def pods(self) -> typing.Optional["PodsMetricSourceV2Beta1"]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec#pods
        '''
        result = self._values.get("pods")
        return typing.cast(typing.Optional["PodsMetricSourceV2Beta1"], result)

    @builtins.property
    def resource(self) -> typing.Optional["ResourceMetricSourceV2Beta1"]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.MetricSpec#resource
        '''
        result = self._values.get("resource")
        return typing.cast(typing.Optional["ResourceMetricSourceV2Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricSpecV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricSpecV2Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "type": "type",
        "container_resource": "containerResource",
        "external": "external",
        "object": "object",
        "pods": "pods",
        "resource": "resource",
    },
)
class MetricSpecV2Beta2:
    def __init__(
        self,
        *,
        type: builtins.str,
        container_resource: typing.Optional[typing.Union[ContainerResourceMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
        external: typing.Optional[typing.Union[ExternalMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
        object: typing.Optional[typing.Union["ObjectMetricSourceV2Beta2", typing.Dict[str, typing.Any]]] = None,
        pods: typing.Optional[typing.Union["PodsMetricSourceV2Beta2", typing.Dict[str, typing.Any]]] = None,
        resource: typing.Optional[typing.Union["ResourceMetricSourceV2Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''MetricSpec specifies how to scale based on a single metric (only ``type`` and one other matching field should be set at once).

        :param type: 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
        :param container_resource: 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 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.
        :param external: 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).
        :param object: object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).
        :param pods: 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.
        :param resource: 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.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec
        '''
        if isinstance(container_resource, dict):
            container_resource = ContainerResourceMetricSourceV2Beta2(**container_resource)
        if isinstance(external, dict):
            external = ExternalMetricSourceV2Beta2(**external)
        if isinstance(object, dict):
            object = ObjectMetricSourceV2Beta2(**object)
        if isinstance(pods, dict):
            pods = PodsMetricSourceV2Beta2(**pods)
        if isinstance(resource, dict):
            resource = ResourceMetricSourceV2Beta2(**resource)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                container_resource: typing.Optional[typing.Union[ContainerResourceMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
                external: typing.Optional[typing.Union[ExternalMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
                object: typing.Optional[typing.Union[ObjectMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
                pods: typing.Optional[typing.Union[PodsMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
                resource: typing.Optional[typing.Union[ResourceMetricSourceV2Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument container_resource", value=container_resource, expected_type=type_hints["container_resource"])
            check_type(argname="argument external", value=external, expected_type=type_hints["external"])
            check_type(argname="argument object", value=object, expected_type=type_hints["object"])
            check_type(argname="argument pods", value=pods, expected_type=type_hints["pods"])
            check_type(argname="argument resource", value=resource, expected_type=type_hints["resource"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if container_resource is not None:
            self._values["container_resource"] = container_resource
        if external is not None:
            self._values["external"] = external
        if object is not None:
            self._values["object"] = object
        if pods is not None:
            self._values["pods"] = pods
        if resource is not None:
            self._values["resource"] = resource

    @builtins.property
    def type(self) -> builtins.str:
        '''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

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def container_resource(
        self,
    ) -> typing.Optional[ContainerResourceMetricSourceV2Beta2]:
        '''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 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.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec#containerResource
        '''
        result = self._values.get("container_resource")
        return typing.cast(typing.Optional[ContainerResourceMetricSourceV2Beta2], result)

    @builtins.property
    def external(self) -> typing.Optional[ExternalMetricSourceV2Beta2]:
        '''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).

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec#external
        '''
        result = self._values.get("external")
        return typing.cast(typing.Optional[ExternalMetricSourceV2Beta2], result)

    @builtins.property
    def object(self) -> typing.Optional["ObjectMetricSourceV2Beta2"]:
        '''object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec#object
        '''
        result = self._values.get("object")
        return typing.cast(typing.Optional["ObjectMetricSourceV2Beta2"], result)

    @builtins.property
    def pods(self) -> typing.Optional["PodsMetricSourceV2Beta2"]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec#pods
        '''
        result = self._values.get("pods")
        return typing.cast(typing.Optional["PodsMetricSourceV2Beta2"], result)

    @builtins.property
    def resource(self) -> typing.Optional["ResourceMetricSourceV2Beta2"]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricSpec#resource
        '''
        result = self._values.get("resource")
        return typing.cast(typing.Optional["ResourceMetricSourceV2Beta2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricSpecV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricTargetV2",
    jsii_struct_bases=[],
    name_mapping={
        "type": "type",
        "average_utilization": "averageUtilization",
        "average_value": "averageValue",
        "value": "value",
    },
)
class MetricTargetV2:
    def __init__(
        self,
        *,
        type: builtins.str,
        average_utilization: typing.Optional[jsii.Number] = None,
        average_value: typing.Optional["Quantity"] = None,
        value: typing.Optional["Quantity"] = None,
    ) -> None:
        '''MetricTarget defines the target value, average value, or average utilization of a specific metric.

        :param type: type represents whether the metric type is Utilization, Value, or AverageValue.
        :param average_utilization: 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
        :param average_value: averageValue is the target value of the average of the metric across all relevant pods (as a quantity).
        :param value: value is the target value of the metric (as a quantity).

        :schema: io.k8s.api.autoscaling.v2.MetricTarget
        '''
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                average_utilization: typing.Optional[jsii.Number] = None,
                average_value: typing.Optional[Quantity] = None,
                value: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument average_utilization", value=average_utilization, expected_type=type_hints["average_utilization"])
            check_type(argname="argument average_value", value=average_value, expected_type=type_hints["average_value"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if average_utilization is not None:
            self._values["average_utilization"] = average_utilization
        if average_value is not None:
            self._values["average_value"] = average_value
        if value is not None:
            self._values["value"] = value

    @builtins.property
    def type(self) -> builtins.str:
        '''type represents whether the metric type is Utilization, Value, or AverageValue.

        :schema: io.k8s.api.autoscaling.v2.MetricTarget#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def average_utilization(self) -> typing.Optional[jsii.Number]:
        '''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

        :schema: io.k8s.api.autoscaling.v2.MetricTarget#averageUtilization
        '''
        result = self._values.get("average_utilization")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def average_value(self) -> typing.Optional["Quantity"]:
        '''averageValue is the target value of the average of the metric across all relevant pods (as a quantity).

        :schema: io.k8s.api.autoscaling.v2.MetricTarget#averageValue
        '''
        result = self._values.get("average_value")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def value(self) -> typing.Optional["Quantity"]:
        '''value is the target value of the metric (as a quantity).

        :schema: io.k8s.api.autoscaling.v2.MetricTarget#value
        '''
        result = self._values.get("value")
        return typing.cast(typing.Optional["Quantity"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricTargetV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MetricTargetV2Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "type": "type",
        "average_utilization": "averageUtilization",
        "average_value": "averageValue",
        "value": "value",
    },
)
class MetricTargetV2Beta2:
    def __init__(
        self,
        *,
        type: builtins.str,
        average_utilization: typing.Optional[jsii.Number] = None,
        average_value: typing.Optional["Quantity"] = None,
        value: typing.Optional["Quantity"] = None,
    ) -> None:
        '''MetricTarget defines the target value, average value, or average utilization of a specific metric.

        :param type: type represents whether the metric type is Utilization, Value, or AverageValue.
        :param average_utilization: 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
        :param average_value: averageValue is the target value of the average of the metric across all relevant pods (as a quantity).
        :param value: value is the target value of the metric (as a quantity).

        :schema: io.k8s.api.autoscaling.v2beta2.MetricTarget
        '''
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                average_utilization: typing.Optional[jsii.Number] = None,
                average_value: typing.Optional[Quantity] = None,
                value: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument average_utilization", value=average_utilization, expected_type=type_hints["average_utilization"])
            check_type(argname="argument average_value", value=average_value, expected_type=type_hints["average_value"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if average_utilization is not None:
            self._values["average_utilization"] = average_utilization
        if average_value is not None:
            self._values["average_value"] = average_value
        if value is not None:
            self._values["value"] = value

    @builtins.property
    def type(self) -> builtins.str:
        '''type represents whether the metric type is Utilization, Value, or AverageValue.

        :schema: io.k8s.api.autoscaling.v2beta2.MetricTarget#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def average_utilization(self) -> typing.Optional[jsii.Number]:
        '''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

        :schema: io.k8s.api.autoscaling.v2beta2.MetricTarget#averageUtilization
        '''
        result = self._values.get("average_utilization")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def average_value(self) -> typing.Optional["Quantity"]:
        '''averageValue is the target value of the average of the metric across all relevant pods (as a quantity).

        :schema: io.k8s.api.autoscaling.v2beta2.MetricTarget#averageValue
        '''
        result = self._values.get("average_value")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def value(self) -> typing.Optional["Quantity"]:
        '''value is the target value of the metric (as a quantity).

        :schema: io.k8s.api.autoscaling.v2beta2.MetricTarget#value
        '''
        result = self._values.get("value")
        return typing.cast(typing.Optional["Quantity"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MetricTargetV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.MutatingWebhook",
    jsii_struct_bases=[],
    name_mapping={
        "admission_review_versions": "admissionReviewVersions",
        "client_config": "clientConfig",
        "name": "name",
        "side_effects": "sideEffects",
        "failure_policy": "failurePolicy",
        "match_policy": "matchPolicy",
        "namespace_selector": "namespaceSelector",
        "object_selector": "objectSelector",
        "reinvocation_policy": "reinvocationPolicy",
        "rules": "rules",
        "timeout_seconds": "timeoutSeconds",
    },
)
class MutatingWebhook:
    def __init__(
        self,
        *,
        admission_review_versions: typing.Sequence[builtins.str],
        client_config: typing.Union["WebhookClientConfig", typing.Dict[str, typing.Any]],
        name: builtins.str,
        side_effects: builtins.str,
        failure_policy: typing.Optional[builtins.str] = None,
        match_policy: typing.Optional[builtins.str] = None,
        namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        object_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        reinvocation_policy: typing.Optional[builtins.str] = None,
        rules: typing.Optional[typing.Sequence[typing.Union["RuleWithOperations", typing.Dict[str, typing.Any]]]] = None,
        timeout_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''MutatingWebhook describes an admission webhook and the resources and operations it applies to.

        :param admission_review_versions: 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 client_config: ClientConfig defines how to communicate with the hook. Required
        :param 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 side_effects: 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 failure_policy: FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail. Default: Fail.
        :param match_policy: 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" Default: Equivalent"
        :param namespace_selector: 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. Default: the empty LabelSelector, which matches everything.
        :param object_selector: 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. Default: the empty LabelSelector, which matches everything.
        :param reinvocation_policy: reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are "Never" and "IfNeeded". Never: the webhook will not be called more than once in a single admission evaluation. IfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead. Defaults to "Never". Default: Never".
        :param 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 timeout_seconds: 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. Default: 10 seconds.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook
        '''
        if isinstance(client_config, dict):
            client_config = WebhookClientConfig(**client_config)
        if isinstance(namespace_selector, dict):
            namespace_selector = LabelSelector(**namespace_selector)
        if isinstance(object_selector, dict):
            object_selector = LabelSelector(**object_selector)
        if __debug__:
            def stub(
                *,
                admission_review_versions: typing.Sequence[builtins.str],
                client_config: typing.Union[WebhookClientConfig, typing.Dict[str, typing.Any]],
                name: builtins.str,
                side_effects: builtins.str,
                failure_policy: typing.Optional[builtins.str] = None,
                match_policy: typing.Optional[builtins.str] = None,
                namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                object_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                reinvocation_policy: typing.Optional[builtins.str] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[RuleWithOperations, typing.Dict[str, typing.Any]]]] = None,
                timeout_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument admission_review_versions", value=admission_review_versions, expected_type=type_hints["admission_review_versions"])
            check_type(argname="argument client_config", value=client_config, expected_type=type_hints["client_config"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument side_effects", value=side_effects, expected_type=type_hints["side_effects"])
            check_type(argname="argument failure_policy", value=failure_policy, expected_type=type_hints["failure_policy"])
            check_type(argname="argument match_policy", value=match_policy, expected_type=type_hints["match_policy"])
            check_type(argname="argument namespace_selector", value=namespace_selector, expected_type=type_hints["namespace_selector"])
            check_type(argname="argument object_selector", value=object_selector, expected_type=type_hints["object_selector"])
            check_type(argname="argument reinvocation_policy", value=reinvocation_policy, expected_type=type_hints["reinvocation_policy"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
            check_type(argname="argument timeout_seconds", value=timeout_seconds, expected_type=type_hints["timeout_seconds"])
        self._values: typing.Dict[str, typing.Any] = {
            "admission_review_versions": admission_review_versions,
            "client_config": client_config,
            "name": name,
            "side_effects": side_effects,
        }
        if failure_policy is not None:
            self._values["failure_policy"] = failure_policy
        if match_policy is not None:
            self._values["match_policy"] = match_policy
        if namespace_selector is not None:
            self._values["namespace_selector"] = namespace_selector
        if object_selector is not None:
            self._values["object_selector"] = object_selector
        if reinvocation_policy is not None:
            self._values["reinvocation_policy"] = reinvocation_policy
        if rules is not None:
            self._values["rules"] = rules
        if timeout_seconds is not None:
            self._values["timeout_seconds"] = timeout_seconds

    @builtins.property
    def admission_review_versions(self) -> typing.List[builtins.str]:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#admissionReviewVersions
        '''
        result = self._values.get("admission_review_versions")
        assert result is not None, "Required property 'admission_review_versions' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def client_config(self) -> "WebhookClientConfig":
        '''ClientConfig defines how to communicate with the hook.

        Required

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#clientConfig
        '''
        result = self._values.get("client_config")
        assert result is not None, "Required property 'client_config' is missing"
        return typing.cast("WebhookClientConfig", result)

    @builtins.property
    def name(self) -> builtins.str:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def side_effects(self) -> builtins.str:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#sideEffects
        '''
        result = self._values.get("side_effects")
        assert result is not None, "Required property 'side_effects' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def failure_policy(self) -> typing.Optional[builtins.str]:
        '''FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail.

        Defaults to Fail.

        :default: Fail.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#failurePolicy
        '''
        result = self._values.get("failure_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def match_policy(self) -> typing.Optional[builtins.str]:
        '''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"

        :default: Equivalent"

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#matchPolicy
        '''
        result = self._values.get("match_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace_selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :default: the empty LabelSelector, which matches everything.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#namespaceSelector
        '''
        result = self._values.get("namespace_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def object_selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :default: the empty LabelSelector, which matches everything.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#objectSelector
        '''
        result = self._values.get("object_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def reinvocation_policy(self) -> typing.Optional[builtins.str]:
        '''reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation.

        Allowed values are "Never" and "IfNeeded".

        Never: the webhook will not be called more than once in a single admission evaluation.

        IfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.

        Defaults to "Never".

        :default: Never".

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#reinvocationPolicy
        '''
        result = self._values.get("reinvocation_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List["RuleWithOperations"]]:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List["RuleWithOperations"]], result)

    @builtins.property
    def timeout_seconds(self) -> typing.Optional[jsii.Number]:
        '''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.

        :default: 10 seconds.

        :schema: io.k8s.api.admissionregistration.v1.MutatingWebhook#timeoutSeconds
        '''
        result = self._values.get("timeout_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MutatingWebhook(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NamespaceSpec",
    jsii_struct_bases=[],
    name_mapping={"finalizers": "finalizers"},
)
class NamespaceSpec:
    def __init__(
        self,
        *,
        finalizers: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''NamespaceSpec describes the attributes on a Namespace.

        :param finalizers: Finalizers is an opaque list of values that must be empty to permanently remove object from storage. More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/

        :schema: io.k8s.api.core.v1.NamespaceSpec
        '''
        if __debug__:
            def stub(
                *,
                finalizers: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument finalizers", value=finalizers, expected_type=type_hints["finalizers"])
        self._values: typing.Dict[str, typing.Any] = {}
        if finalizers is not None:
            self._values["finalizers"] = finalizers

    @builtins.property
    def finalizers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Finalizers is an opaque list of values that must be empty to permanently remove object from storage.

        More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/

        :schema: io.k8s.api.core.v1.NamespaceSpec#finalizers
        '''
        result = self._values.get("finalizers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NamespaceSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NetworkPolicyEgressRule",
    jsii_struct_bases=[],
    name_mapping={"ports": "ports", "to": "to"},
)
class NetworkPolicyEgressRule:
    def __init__(
        self,
        *,
        ports: typing.Optional[typing.Sequence[typing.Union["NetworkPolicyPort", typing.Dict[str, typing.Any]]]] = None,
        to: typing.Optional[typing.Sequence[typing.Union["NetworkPolicyPeer", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector.

        The traffic must match both ports and to. This type is beta-level in 1.8

        :param ports: List of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.
        :param to: List of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.

        :schema: io.k8s.api.networking.v1.NetworkPolicyEgressRule
        '''
        if __debug__:
            def stub(
                *,
                ports: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyPort, typing.Dict[str, typing.Any]]]] = None,
                to: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyPeer, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
            check_type(argname="argument to", value=to, expected_type=type_hints["to"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ports is not None:
            self._values["ports"] = ports
        if to is not None:
            self._values["to"] = to

    @builtins.property
    def ports(self) -> typing.Optional[typing.List["NetworkPolicyPort"]]:
        '''List of destination ports for outgoing traffic.

        Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.

        :schema: io.k8s.api.networking.v1.NetworkPolicyEgressRule#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List["NetworkPolicyPort"]], result)

    @builtins.property
    def to(self) -> typing.Optional[typing.List["NetworkPolicyPeer"]]:
        '''List of destinations for outgoing traffic of pods selected for this rule.

        Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.

        :schema: io.k8s.api.networking.v1.NetworkPolicyEgressRule#to
        '''
        result = self._values.get("to")
        return typing.cast(typing.Optional[typing.List["NetworkPolicyPeer"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkPolicyEgressRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NetworkPolicyIngressRule",
    jsii_struct_bases=[],
    name_mapping={"from_": "from", "ports": "ports"},
)
class NetworkPolicyIngressRule:
    def __init__(
        self,
        *,
        from_: typing.Optional[typing.Sequence[typing.Union["NetworkPolicyPeer", typing.Dict[str, typing.Any]]]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union["NetworkPolicyPort", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a NetworkPolicySpec's podSelector.

        The traffic must match both ports and from.

        :param from_: List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.
        :param ports: List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.

        :schema: io.k8s.api.networking.v1.NetworkPolicyIngressRule
        '''
        if __debug__:
            def stub(
                *,
                from_: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyPeer, typing.Dict[str, typing.Any]]]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyPort, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument from_", value=from_, expected_type=type_hints["from_"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
        self._values: typing.Dict[str, typing.Any] = {}
        if from_ is not None:
            self._values["from_"] = from_
        if ports is not None:
            self._values["ports"] = ports

    @builtins.property
    def from_(self) -> typing.Optional[typing.List["NetworkPolicyPeer"]]:
        '''List of sources which should be able to access the pods selected for this rule.

        Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.

        :schema: io.k8s.api.networking.v1.NetworkPolicyIngressRule#from
        '''
        result = self._values.get("from_")
        return typing.cast(typing.Optional[typing.List["NetworkPolicyPeer"]], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List["NetworkPolicyPort"]]:
        '''List of ports which should be made accessible on the pods selected for this rule.

        Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.

        :schema: io.k8s.api.networking.v1.NetworkPolicyIngressRule#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List["NetworkPolicyPort"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkPolicyIngressRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NetworkPolicyPeer",
    jsii_struct_bases=[],
    name_mapping={
        "ip_block": "ipBlock",
        "namespace_selector": "namespaceSelector",
        "pod_selector": "podSelector",
    },
)
class NetworkPolicyPeer:
    def __init__(
        self,
        *,
        ip_block: typing.Optional[typing.Union[IpBlock, typing.Dict[str, typing.Any]]] = None,
        namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        pod_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''NetworkPolicyPeer describes a peer to allow traffic to/from.

        Only certain combinations of fields are allowed

        :param ip_block: IPBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be.
        :param namespace_selector: Selects Namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces. If PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.
        :param pod_selector: This is a label selector which selects Pods. This field follows standard label selector semantics; if present but empty, it selects all pods. If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPeer
        '''
        if isinstance(ip_block, dict):
            ip_block = IpBlock(**ip_block)
        if isinstance(namespace_selector, dict):
            namespace_selector = LabelSelector(**namespace_selector)
        if isinstance(pod_selector, dict):
            pod_selector = LabelSelector(**pod_selector)
        if __debug__:
            def stub(
                *,
                ip_block: typing.Optional[typing.Union[IpBlock, typing.Dict[str, typing.Any]]] = None,
                namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                pod_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ip_block", value=ip_block, expected_type=type_hints["ip_block"])
            check_type(argname="argument namespace_selector", value=namespace_selector, expected_type=type_hints["namespace_selector"])
            check_type(argname="argument pod_selector", value=pod_selector, expected_type=type_hints["pod_selector"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ip_block is not None:
            self._values["ip_block"] = ip_block
        if namespace_selector is not None:
            self._values["namespace_selector"] = namespace_selector
        if pod_selector is not None:
            self._values["pod_selector"] = pod_selector

    @builtins.property
    def ip_block(self) -> typing.Optional[IpBlock]:
        '''IPBlock defines policy on a particular IPBlock.

        If this field is set then neither of the other fields can be.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPeer#ipBlock
        '''
        result = self._values.get("ip_block")
        return typing.cast(typing.Optional[IpBlock], result)

    @builtins.property
    def namespace_selector(self) -> typing.Optional[LabelSelector]:
        '''Selects Namespaces using cluster-scoped labels.

        This field follows standard label selector semantics; if present but empty, it selects all namespaces.

        If PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPeer#namespaceSelector
        '''
        result = self._values.get("namespace_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def pod_selector(self) -> typing.Optional[LabelSelector]:
        '''This is a label selector which selects Pods.

        This field follows standard label selector semantics; if present but empty, it selects all pods.

        If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPeer#podSelector
        '''
        result = self._values.get("pod_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkPolicyPeer(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NetworkPolicyPort",
    jsii_struct_bases=[],
    name_mapping={"end_port": "endPort", "port": "port", "protocol": "protocol"},
)
class NetworkPolicyPort:
    def __init__(
        self,
        *,
        end_port: typing.Optional[jsii.Number] = None,
        port: typing.Optional[IntOrString] = None,
        protocol: typing.Optional[builtins.str] = None,
    ) -> None:
        '''NetworkPolicyPort describes a port to allow traffic on.

        :param end_port: If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. This feature is in Beta state and is enabled by default. It can be disabled using the Feature Gate "NetworkPolicyEndPort".
        :param port: The port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.
        :param protocol: The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPort
        '''
        if __debug__:
            def stub(
                *,
                end_port: typing.Optional[jsii.Number] = None,
                port: typing.Optional[IntOrString] = None,
                protocol: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument end_port", value=end_port, expected_type=type_hints["end_port"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
        self._values: typing.Dict[str, typing.Any] = {}
        if end_port is not None:
            self._values["end_port"] = end_port
        if port is not None:
            self._values["port"] = port
        if protocol is not None:
            self._values["protocol"] = protocol

    @builtins.property
    def end_port(self) -> typing.Optional[jsii.Number]:
        '''If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy.

        This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. This feature is in Beta state and is enabled by default. It can be disabled using the Feature Gate "NetworkPolicyEndPort".

        :schema: io.k8s.api.networking.v1.NetworkPolicyPort#endPort
        '''
        result = self._values.get("end_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def port(self) -> typing.Optional[IntOrString]:
        '''The port on the given protocol.

        This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPort#port
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def protocol(self) -> typing.Optional[builtins.str]:
        '''The protocol (TCP, UDP, or SCTP) which traffic must match.

        If not specified, this field defaults to TCP.

        :schema: io.k8s.api.networking.v1.NetworkPolicyPort#protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkPolicyPort(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NetworkPolicySpec",
    jsii_struct_bases=[],
    name_mapping={
        "pod_selector": "podSelector",
        "egress": "egress",
        "ingress": "ingress",
        "policy_types": "policyTypes",
    },
)
class NetworkPolicySpec:
    def __init__(
        self,
        *,
        pod_selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
        egress: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyEgressRule, typing.Dict[str, typing.Any]]]] = None,
        ingress: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyIngressRule, typing.Dict[str, typing.Any]]]] = None,
        policy_types: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''NetworkPolicySpec provides the specification of a NetworkPolicy.

        :param pod_selector: Selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.
        :param egress: List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8
        :param ingress: List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)
        :param policy_types: List of rule types that the NetworkPolicy relates to. Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include "Egress" (since such a policy would not include an Egress section and would otherwise default to just [ "Ingress" ]). This field is beta-level in 1.8

        :schema: io.k8s.api.networking.v1.NetworkPolicySpec
        '''
        if isinstance(pod_selector, dict):
            pod_selector = LabelSelector(**pod_selector)
        if __debug__:
            def stub(
                *,
                pod_selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
                egress: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyEgressRule, typing.Dict[str, typing.Any]]]] = None,
                ingress: typing.Optional[typing.Sequence[typing.Union[NetworkPolicyIngressRule, typing.Dict[str, typing.Any]]]] = None,
                policy_types: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pod_selector", value=pod_selector, expected_type=type_hints["pod_selector"])
            check_type(argname="argument egress", value=egress, expected_type=type_hints["egress"])
            check_type(argname="argument ingress", value=ingress, expected_type=type_hints["ingress"])
            check_type(argname="argument policy_types", value=policy_types, expected_type=type_hints["policy_types"])
        self._values: typing.Dict[str, typing.Any] = {
            "pod_selector": pod_selector,
        }
        if egress is not None:
            self._values["egress"] = egress
        if ingress is not None:
            self._values["ingress"] = ingress
        if policy_types is not None:
            self._values["policy_types"] = policy_types

    @builtins.property
    def pod_selector(self) -> LabelSelector:
        '''Selects the pods to which this NetworkPolicy object applies.

        The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.

        :schema: io.k8s.api.networking.v1.NetworkPolicySpec#podSelector
        '''
        result = self._values.get("pod_selector")
        assert result is not None, "Required property 'pod_selector' is missing"
        return typing.cast(LabelSelector, result)

    @builtins.property
    def egress(self) -> typing.Optional[typing.List[NetworkPolicyEgressRule]]:
        '''List of egress rules to be applied to the selected pods.

        Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8

        :schema: io.k8s.api.networking.v1.NetworkPolicySpec#egress
        '''
        result = self._values.get("egress")
        return typing.cast(typing.Optional[typing.List[NetworkPolicyEgressRule]], result)

    @builtins.property
    def ingress(self) -> typing.Optional[typing.List[NetworkPolicyIngressRule]]:
        '''List of ingress rules to be applied to the selected pods.

        Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)

        :schema: io.k8s.api.networking.v1.NetworkPolicySpec#ingress
        '''
        result = self._values.get("ingress")
        return typing.cast(typing.Optional[typing.List[NetworkPolicyIngressRule]], result)

    @builtins.property
    def policy_types(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of rule types that the NetworkPolicy relates to.

        Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include "Egress" (since such a policy would not include an Egress section and would otherwise default to just [ "Ingress" ]). This field is beta-level in 1.8

        :schema: io.k8s.api.networking.v1.NetworkPolicySpec#policyTypes
        '''
        result = self._values.get("policy_types")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkPolicySpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NfsVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"path": "path", "server": "server", "read_only": "readOnly"},
)
class NfsVolumeSource:
    def __init__(
        self,
        *,
        path: builtins.str,
        server: builtins.str,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Represents an NFS mount that lasts the lifetime of a pod.

        NFS volumes do not support ownership management or SELinux relabeling.

        :param path: Path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
        :param server: Server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
        :param read_only: ReadOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs Default: false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

        :schema: io.k8s.api.core.v1.NFSVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                path: builtins.str,
                server: builtins.str,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument server", value=server, expected_type=type_hints["server"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "path": path,
            "server": server,
        }
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def path(self) -> builtins.str:
        '''Path that is exported by the NFS server.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

        :schema: io.k8s.api.core.v1.NFSVolumeSource#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def server(self) -> builtins.str:
        '''Server is the hostname or IP address of the NFS server.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

        :schema: io.k8s.api.core.v1.NFSVolumeSource#server
        '''
        result = self._values.get("server")
        assert result is not None, "Required property 'server' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the NFS export to be mounted with read-only permissions.

        Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

        :default: false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

        :schema: io.k8s.api.core.v1.NFSVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NfsVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NodeAffinity",
    jsii_struct_bases=[],
    name_mapping={
        "preferred_during_scheduling_ignored_during_execution": "preferredDuringSchedulingIgnoredDuringExecution",
        "required_during_scheduling_ignored_during_execution": "requiredDuringSchedulingIgnoredDuringExecution",
    },
)
class NodeAffinity:
    def __init__(
        self,
        *,
        preferred_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union["PreferredSchedulingTerm", typing.Dict[str, typing.Any]]]] = None,
        required_during_scheduling_ignored_during_execution: typing.Optional[typing.Union["NodeSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Node affinity is a group of node affinity scheduling rules.

        :param preferred_during_scheduling_ignored_during_execution: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.
        :param required_during_scheduling_ignored_during_execution: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

        :schema: io.k8s.api.core.v1.NodeAffinity
        '''
        if isinstance(required_during_scheduling_ignored_during_execution, dict):
            required_during_scheduling_ignored_during_execution = NodeSelector(**required_during_scheduling_ignored_during_execution)
        if __debug__:
            def stub(
                *,
                preferred_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union[PreferredSchedulingTerm, typing.Dict[str, typing.Any]]]] = None,
                required_during_scheduling_ignored_during_execution: typing.Optional[typing.Union[NodeSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument preferred_during_scheduling_ignored_during_execution", value=preferred_during_scheduling_ignored_during_execution, expected_type=type_hints["preferred_during_scheduling_ignored_during_execution"])
            check_type(argname="argument required_during_scheduling_ignored_during_execution", value=required_during_scheduling_ignored_during_execution, expected_type=type_hints["required_during_scheduling_ignored_during_execution"])
        self._values: typing.Dict[str, typing.Any] = {}
        if preferred_during_scheduling_ignored_during_execution is not None:
            self._values["preferred_during_scheduling_ignored_during_execution"] = preferred_during_scheduling_ignored_during_execution
        if required_during_scheduling_ignored_during_execution is not None:
            self._values["required_during_scheduling_ignored_during_execution"] = required_during_scheduling_ignored_during_execution

    @builtins.property
    def preferred_during_scheduling_ignored_during_execution(
        self,
    ) -> typing.Optional[typing.List["PreferredSchedulingTerm"]]:
        '''The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions.

        The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.

        :schema: io.k8s.api.core.v1.NodeAffinity#preferredDuringSchedulingIgnoredDuringExecution
        '''
        result = self._values.get("preferred_during_scheduling_ignored_during_execution")
        return typing.cast(typing.Optional[typing.List["PreferredSchedulingTerm"]], result)

    @builtins.property
    def required_during_scheduling_ignored_during_execution(
        self,
    ) -> typing.Optional["NodeSelector"]:
        '''If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node.

        If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

        :schema: io.k8s.api.core.v1.NodeAffinity#requiredDuringSchedulingIgnoredDuringExecution
        '''
        result = self._values.get("required_during_scheduling_ignored_during_execution")
        return typing.cast(typing.Optional["NodeSelector"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NodeAffinity(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NodeConfigSource",
    jsii_struct_bases=[],
    name_mapping={"config_map": "configMap"},
)
class NodeConfigSource:
    def __init__(
        self,
        *,
        config_map: typing.Optional[typing.Union[ConfigMapNodeConfigSource, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''NodeConfigSource specifies a source of node configuration.

        Exactly one subfield (excluding metadata) must be non-nil. This API is deprecated since 1.22

        :param config_map: ConfigMap is a reference to a Node's ConfigMap.

        :schema: io.k8s.api.core.v1.NodeConfigSource
        '''
        if isinstance(config_map, dict):
            config_map = ConfigMapNodeConfigSource(**config_map)
        if __debug__:
            def stub(
                *,
                config_map: typing.Optional[typing.Union[ConfigMapNodeConfigSource, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument config_map", value=config_map, expected_type=type_hints["config_map"])
        self._values: typing.Dict[str, typing.Any] = {}
        if config_map is not None:
            self._values["config_map"] = config_map

    @builtins.property
    def config_map(self) -> typing.Optional[ConfigMapNodeConfigSource]:
        '''ConfigMap is a reference to a Node's ConfigMap.

        :schema: io.k8s.api.core.v1.NodeConfigSource#configMap
        '''
        result = self._values.get("config_map")
        return typing.cast(typing.Optional[ConfigMapNodeConfigSource], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NodeConfigSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NodeSelector",
    jsii_struct_bases=[],
    name_mapping={"node_selector_terms": "nodeSelectorTerms"},
)
class NodeSelector:
    def __init__(
        self,
        *,
        node_selector_terms: typing.Sequence[typing.Union["NodeSelectorTerm", typing.Dict[str, typing.Any]]],
    ) -> None:
        '''A node selector represents the union of the results of one or more label queries over a set of nodes;

        that is, it represents the OR of the selectors represented by the node selector terms.

        :param node_selector_terms: Required. A list of node selector terms. The terms are ORed.

        :schema: io.k8s.api.core.v1.NodeSelector
        '''
        if __debug__:
            def stub(
                *,
                node_selector_terms: typing.Sequence[typing.Union[NodeSelectorTerm, typing.Dict[str, typing.Any]]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument node_selector_terms", value=node_selector_terms, expected_type=type_hints["node_selector_terms"])
        self._values: typing.Dict[str, typing.Any] = {
            "node_selector_terms": node_selector_terms,
        }

    @builtins.property
    def node_selector_terms(self) -> typing.List["NodeSelectorTerm"]:
        '''Required.

        A list of node selector terms. The terms are ORed.

        :schema: io.k8s.api.core.v1.NodeSelector#nodeSelectorTerms
        '''
        result = self._values.get("node_selector_terms")
        assert result is not None, "Required property 'node_selector_terms' is missing"
        return typing.cast(typing.List["NodeSelectorTerm"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NodeSelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NodeSelectorRequirement",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "operator": "operator", "values": "values"},
)
class NodeSelectorRequirement:
    def __init__(
        self,
        *,
        key: builtins.str,
        operator: IoK8SApiCoreV1NodeSelectorRequirementOperator,
        values: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

        :param key: The label key that the selector applies to.
        :param operator: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. Possible enum values: - ``"DoesNotExist"`` - ``"Exists"`` - ``"Gt"`` - ``"In"`` - ``"Lt"`` - ``"NotIn"``
        :param values: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

        :schema: io.k8s.api.core.v1.NodeSelectorRequirement
        '''
        if __debug__:
            def stub(
                *,
                key: builtins.str,
                operator: IoK8SApiCoreV1NodeSelectorRequirementOperator,
                values: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument operator", value=operator, expected_type=type_hints["operator"])
            check_type(argname="argument values", value=values, expected_type=type_hints["values"])
        self._values: typing.Dict[str, typing.Any] = {
            "key": key,
            "operator": operator,
        }
        if values is not None:
            self._values["values"] = values

    @builtins.property
    def key(self) -> builtins.str:
        '''The label key that the selector applies to.

        :schema: io.k8s.api.core.v1.NodeSelectorRequirement#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def operator(self) -> IoK8SApiCoreV1NodeSelectorRequirementOperator:
        '''Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

        Possible enum values:

        - ``"DoesNotExist"``
        - ``"Exists"``
        - ``"Gt"``
        - ``"In"``
        - ``"Lt"``
        - ``"NotIn"``

        :schema: io.k8s.api.core.v1.NodeSelectorRequirement#operator
        '''
        result = self._values.get("operator")
        assert result is not None, "Required property 'operator' is missing"
        return typing.cast(IoK8SApiCoreV1NodeSelectorRequirementOperator, result)

    @builtins.property
    def values(self) -> typing.Optional[typing.List[builtins.str]]:
        '''An array of string values.

        If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

        :schema: io.k8s.api.core.v1.NodeSelectorRequirement#values
        '''
        result = self._values.get("values")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NodeSelectorRequirement(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NodeSelectorTerm",
    jsii_struct_bases=[],
    name_mapping={
        "match_expressions": "matchExpressions",
        "match_fields": "matchFields",
    },
)
class NodeSelectorTerm:
    def __init__(
        self,
        *,
        match_expressions: typing.Optional[typing.Sequence[typing.Union[NodeSelectorRequirement, typing.Dict[str, typing.Any]]]] = None,
        match_fields: typing.Optional[typing.Sequence[typing.Union[NodeSelectorRequirement, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''A null or empty node selector term matches no objects.

        The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.

        :param match_expressions: A list of node selector requirements by node's labels.
        :param match_fields: A list of node selector requirements by node's fields.

        :schema: io.k8s.api.core.v1.NodeSelectorTerm
        '''
        if __debug__:
            def stub(
                *,
                match_expressions: typing.Optional[typing.Sequence[typing.Union[NodeSelectorRequirement, typing.Dict[str, typing.Any]]]] = None,
                match_fields: typing.Optional[typing.Sequence[typing.Union[NodeSelectorRequirement, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument match_expressions", value=match_expressions, expected_type=type_hints["match_expressions"])
            check_type(argname="argument match_fields", value=match_fields, expected_type=type_hints["match_fields"])
        self._values: typing.Dict[str, typing.Any] = {}
        if match_expressions is not None:
            self._values["match_expressions"] = match_expressions
        if match_fields is not None:
            self._values["match_fields"] = match_fields

    @builtins.property
    def match_expressions(
        self,
    ) -> typing.Optional[typing.List[NodeSelectorRequirement]]:
        '''A list of node selector requirements by node's labels.

        :schema: io.k8s.api.core.v1.NodeSelectorTerm#matchExpressions
        '''
        result = self._values.get("match_expressions")
        return typing.cast(typing.Optional[typing.List[NodeSelectorRequirement]], result)

    @builtins.property
    def match_fields(self) -> typing.Optional[typing.List[NodeSelectorRequirement]]:
        '''A list of node selector requirements by node's fields.

        :schema: io.k8s.api.core.v1.NodeSelectorTerm#matchFields
        '''
        result = self._values.get("match_fields")
        return typing.cast(typing.Optional[typing.List[NodeSelectorRequirement]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NodeSelectorTerm(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NodeSpec",
    jsii_struct_bases=[],
    name_mapping={
        "config_source": "configSource",
        "external_id": "externalId",
        "pod_cidr": "podCidr",
        "pod_cid_rs": "podCidRs",
        "provider_id": "providerId",
        "taints": "taints",
        "unschedulable": "unschedulable",
    },
)
class NodeSpec:
    def __init__(
        self,
        *,
        config_source: typing.Optional[typing.Union[NodeConfigSource, typing.Dict[str, typing.Any]]] = None,
        external_id: typing.Optional[builtins.str] = None,
        pod_cidr: typing.Optional[builtins.str] = None,
        pod_cid_rs: typing.Optional[typing.Sequence[builtins.str]] = None,
        provider_id: typing.Optional[builtins.str] = None,
        taints: typing.Optional[typing.Sequence[typing.Union["Taint", typing.Dict[str, typing.Any]]]] = None,
        unschedulable: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''NodeSpec describes the attributes that a node is created with.

        :param config_source: Deprecated. If specified, the source of the node's configuration. The DynamicKubeletConfig feature gate must be enabled for the Kubelet to use this field. This field is deprecated as of 1.22: https://git.k8s.io/enhancements/keps/sig-node/281-dynamic-kubelet-configuration
        :param external_id: Deprecated. Not all kubelets will set this field. Remove field after 1.13. see: https://issues.k8s.io/61966
        :param pod_cidr: PodCIDR represents the pod IP range assigned to the node.
        :param pod_cid_rs: podCIDRs represents the IP ranges assigned to the node for usage by Pods on that node. If this field is specified, the 0th entry must match the podCIDR field. It may contain at most 1 value for each of IPv4 and IPv6.
        :param provider_id: ID of the node assigned by the cloud provider in the format: ://.
        :param taints: If specified, the node's taints.
        :param unschedulable: Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: https://kubernetes.io/docs/concepts/nodes/node/#manual-node-administration

        :schema: io.k8s.api.core.v1.NodeSpec
        '''
        if isinstance(config_source, dict):
            config_source = NodeConfigSource(**config_source)
        if __debug__:
            def stub(
                *,
                config_source: typing.Optional[typing.Union[NodeConfigSource, typing.Dict[str, typing.Any]]] = None,
                external_id: typing.Optional[builtins.str] = None,
                pod_cidr: typing.Optional[builtins.str] = None,
                pod_cid_rs: typing.Optional[typing.Sequence[builtins.str]] = None,
                provider_id: typing.Optional[builtins.str] = None,
                taints: typing.Optional[typing.Sequence[typing.Union[Taint, typing.Dict[str, typing.Any]]]] = None,
                unschedulable: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument config_source", value=config_source, expected_type=type_hints["config_source"])
            check_type(argname="argument external_id", value=external_id, expected_type=type_hints["external_id"])
            check_type(argname="argument pod_cidr", value=pod_cidr, expected_type=type_hints["pod_cidr"])
            check_type(argname="argument pod_cid_rs", value=pod_cid_rs, expected_type=type_hints["pod_cid_rs"])
            check_type(argname="argument provider_id", value=provider_id, expected_type=type_hints["provider_id"])
            check_type(argname="argument taints", value=taints, expected_type=type_hints["taints"])
            check_type(argname="argument unschedulable", value=unschedulable, expected_type=type_hints["unschedulable"])
        self._values: typing.Dict[str, typing.Any] = {}
        if config_source is not None:
            self._values["config_source"] = config_source
        if external_id is not None:
            self._values["external_id"] = external_id
        if pod_cidr is not None:
            self._values["pod_cidr"] = pod_cidr
        if pod_cid_rs is not None:
            self._values["pod_cid_rs"] = pod_cid_rs
        if provider_id is not None:
            self._values["provider_id"] = provider_id
        if taints is not None:
            self._values["taints"] = taints
        if unschedulable is not None:
            self._values["unschedulable"] = unschedulable

    @builtins.property
    def config_source(self) -> typing.Optional[NodeConfigSource]:
        '''Deprecated.

        If specified, the source of the node's configuration. The DynamicKubeletConfig feature gate must be enabled for the Kubelet to use this field. This field is deprecated as of 1.22: https://git.k8s.io/enhancements/keps/sig-node/281-dynamic-kubelet-configuration

        :schema: io.k8s.api.core.v1.NodeSpec#configSource
        '''
        result = self._values.get("config_source")
        return typing.cast(typing.Optional[NodeConfigSource], result)

    @builtins.property
    def external_id(self) -> typing.Optional[builtins.str]:
        '''Deprecated.

        Not all kubelets will set this field. Remove field after 1.13. see: https://issues.k8s.io/61966

        :schema: io.k8s.api.core.v1.NodeSpec#externalID
        '''
        result = self._values.get("external_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def pod_cidr(self) -> typing.Optional[builtins.str]:
        '''PodCIDR represents the pod IP range assigned to the node.

        :schema: io.k8s.api.core.v1.NodeSpec#podCIDR
        '''
        result = self._values.get("pod_cidr")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def pod_cid_rs(self) -> typing.Optional[typing.List[builtins.str]]:
        '''podCIDRs represents the IP ranges assigned to the node for usage by Pods on that node.

        If this field is specified, the 0th entry must match the podCIDR field. It may contain at most 1 value for each of IPv4 and IPv6.

        :schema: io.k8s.api.core.v1.NodeSpec#podCIDRs
        '''
        result = self._values.get("pod_cid_rs")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def provider_id(self) -> typing.Optional[builtins.str]:
        '''ID of the node assigned by the cloud provider in the format: ://.

        :schema: io.k8s.api.core.v1.NodeSpec#providerID
        '''
        result = self._values.get("provider_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def taints(self) -> typing.Optional[typing.List["Taint"]]:
        '''If specified, the node's taints.

        :schema: io.k8s.api.core.v1.NodeSpec#taints
        '''
        result = self._values.get("taints")
        return typing.cast(typing.Optional[typing.List["Taint"]], result)

    @builtins.property
    def unschedulable(self) -> typing.Optional[builtins.bool]:
        '''Unschedulable controls node schedulability of new pods.

        By default, node is schedulable. More info: https://kubernetes.io/docs/concepts/nodes/node/#manual-node-administration

        :schema: io.k8s.api.core.v1.NodeSpec#unschedulable
        '''
        result = self._values.get("unschedulable")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NodeSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NonResourceAttributes",
    jsii_struct_bases=[],
    name_mapping={"path": "path", "verb": "verb"},
)
class NonResourceAttributes:
    def __init__(
        self,
        *,
        path: typing.Optional[builtins.str] = None,
        verb: typing.Optional[builtins.str] = None,
    ) -> None:
        '''NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface.

        :param path: Path is the URL path of the request.
        :param verb: Verb is the standard HTTP verb.

        :schema: io.k8s.api.authorization.v1.NonResourceAttributes
        '''
        if __debug__:
            def stub(
                *,
                path: typing.Optional[builtins.str] = None,
                verb: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument verb", value=verb, expected_type=type_hints["verb"])
        self._values: typing.Dict[str, typing.Any] = {}
        if path is not None:
            self._values["path"] = path
        if verb is not None:
            self._values["verb"] = verb

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''Path is the URL path of the request.

        :schema: io.k8s.api.authorization.v1.NonResourceAttributes#path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def verb(self) -> typing.Optional[builtins.str]:
        '''Verb is the standard HTTP verb.

        :schema: io.k8s.api.authorization.v1.NonResourceAttributes#verb
        '''
        result = self._values.get("verb")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NonResourceAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NonResourcePolicyRuleV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"non_resource_ur_ls": "nonResourceUrLs", "verbs": "verbs"},
)
class NonResourcePolicyRuleV1Beta1:
    def __init__(
        self,
        *,
        non_resource_ur_ls: typing.Sequence[builtins.str],
        verbs: typing.Sequence[builtins.str],
    ) -> None:
        '''NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the target non-resource URL.

        A NonResourcePolicyRule matches a request if and only if both (a) at least one member of verbs matches the request and (b) at least one member of nonResourceURLs matches the request.

        :param non_resource_ur_ls: ``nonResourceURLs`` is a set of url prefixes that a user should have access to and may not be empty. For example: - "/healthz" is legal - "/hea*" is illegal - "/hea" is legal but matches nothing - "/hea/*" also matches nothing - "/healthz/*" matches all per-component health checks. "*" matches all non-resource urls. if it is present, it must be the only entry. Required.
        :param verbs: ``verbs`` is a list of matching verbs and may not be empty. "*" matches all verbs. If it is present, it must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule
        '''
        if __debug__:
            def stub(
                *,
                non_resource_ur_ls: typing.Sequence[builtins.str],
                verbs: typing.Sequence[builtins.str],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument non_resource_ur_ls", value=non_resource_ur_ls, expected_type=type_hints["non_resource_ur_ls"])
            check_type(argname="argument verbs", value=verbs, expected_type=type_hints["verbs"])
        self._values: typing.Dict[str, typing.Any] = {
            "non_resource_ur_ls": non_resource_ur_ls,
            "verbs": verbs,
        }

    @builtins.property
    def non_resource_ur_ls(self) -> typing.List[builtins.str]:
        '''``nonResourceURLs`` is a set of url prefixes that a user should have access to and may not be empty.

        For example:

        - "/healthz" is legal
        - "/hea*" is illegal
        - "/hea" is legal but matches nothing
        - "/hea/*" also matches nothing
        - "/healthz/*" matches all per-component health checks.
          "*" matches all non-resource urls. if it is present, it must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule#nonResourceURLs
        '''
        result = self._values.get("non_resource_ur_ls")
        assert result is not None, "Required property 'non_resource_ur_ls' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def verbs(self) -> typing.List[builtins.str]:
        '''``verbs`` is a list of matching verbs and may not be empty.

        "*" matches all verbs. If it is present, it must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule#verbs
        '''
        result = self._values.get("verbs")
        assert result is not None, "Required property 'verbs' is missing"
        return typing.cast(typing.List[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NonResourcePolicyRuleV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.NonResourcePolicyRuleV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"non_resource_ur_ls": "nonResourceUrLs", "verbs": "verbs"},
)
class NonResourcePolicyRuleV1Beta2:
    def __init__(
        self,
        *,
        non_resource_ur_ls: typing.Sequence[builtins.str],
        verbs: typing.Sequence[builtins.str],
    ) -> None:
        '''NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the target non-resource URL.

        A NonResourcePolicyRule matches a request if and only if both (a) at least one member of verbs matches the request and (b) at least one member of nonResourceURLs matches the request.

        :param non_resource_ur_ls: ``nonResourceURLs`` is a set of url prefixes that a user should have access to and may not be empty. For example: - "/healthz" is legal - "/hea*" is illegal - "/hea" is legal but matches nothing - "/hea/*" also matches nothing - "/healthz/*" matches all per-component health checks. "*" matches all non-resource urls. if it is present, it must be the only entry. Required.
        :param verbs: ``verbs`` is a list of matching verbs and may not be empty. "*" matches all verbs. If it is present, it must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule
        '''
        if __debug__:
            def stub(
                *,
                non_resource_ur_ls: typing.Sequence[builtins.str],
                verbs: typing.Sequence[builtins.str],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument non_resource_ur_ls", value=non_resource_ur_ls, expected_type=type_hints["non_resource_ur_ls"])
            check_type(argname="argument verbs", value=verbs, expected_type=type_hints["verbs"])
        self._values: typing.Dict[str, typing.Any] = {
            "non_resource_ur_ls": non_resource_ur_ls,
            "verbs": verbs,
        }

    @builtins.property
    def non_resource_ur_ls(self) -> typing.List[builtins.str]:
        '''``nonResourceURLs`` is a set of url prefixes that a user should have access to and may not be empty.

        For example:

        - "/healthz" is legal
        - "/hea*" is illegal
        - "/hea" is legal but matches nothing
        - "/hea/*" also matches nothing
        - "/healthz/*" matches all per-component health checks.
          "*" matches all non-resource urls. if it is present, it must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule#nonResourceURLs
        '''
        result = self._values.get("non_resource_ur_ls")
        assert result is not None, "Required property 'non_resource_ur_ls' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def verbs(self) -> typing.List[builtins.str]:
        '''``verbs`` is a list of matching verbs and may not be empty.

        "*" matches all verbs. If it is present, it must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule#verbs
        '''
        result = self._values.get("verbs")
        assert result is not None, "Required property 'verbs' is missing"
        return typing.cast(typing.List[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NonResourcePolicyRuleV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ObjectFieldSelector",
    jsii_struct_bases=[],
    name_mapping={"field_path": "fieldPath", "api_version": "apiVersion"},
)
class ObjectFieldSelector:
    def __init__(
        self,
        *,
        field_path: builtins.str,
        api_version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ObjectFieldSelector selects an APIVersioned field of an object.

        :param field_path: Path of the field to select in the specified API version.
        :param api_version: Version of the schema the FieldPath is written in terms of, defaults to "v1".

        :schema: io.k8s.api.core.v1.ObjectFieldSelector
        '''
        if __debug__:
            def stub(
                *,
                field_path: builtins.str,
                api_version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument field_path", value=field_path, expected_type=type_hints["field_path"])
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
        self._values: typing.Dict[str, typing.Any] = {
            "field_path": field_path,
        }
        if api_version is not None:
            self._values["api_version"] = api_version

    @builtins.property
    def field_path(self) -> builtins.str:
        '''Path of the field to select in the specified API version.

        :schema: io.k8s.api.core.v1.ObjectFieldSelector#fieldPath
        '''
        result = self._values.get("field_path")
        assert result is not None, "Required property 'field_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''Version of the schema the FieldPath is written in terms of, defaults to "v1".

        :schema: io.k8s.api.core.v1.ObjectFieldSelector#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ObjectFieldSelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ObjectMeta",
    jsii_struct_bases=[],
    name_mapping={
        "annotations": "annotations",
        "cluster_name": "clusterName",
        "creation_timestamp": "creationTimestamp",
        "deletion_grace_period_seconds": "deletionGracePeriodSeconds",
        "deletion_timestamp": "deletionTimestamp",
        "finalizers": "finalizers",
        "generate_name": "generateName",
        "generation": "generation",
        "labels": "labels",
        "managed_fields": "managedFields",
        "name": "name",
        "namespace": "namespace",
        "owner_references": "ownerReferences",
        "resource_version": "resourceVersion",
        "self_link": "selfLink",
        "uid": "uid",
    },
)
class ObjectMeta:
    def __init__(
        self,
        *,
        annotations: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        cluster_name: typing.Optional[builtins.str] = None,
        creation_timestamp: typing.Optional[datetime.datetime] = None,
        deletion_grace_period_seconds: typing.Optional[jsii.Number] = None,
        deletion_timestamp: typing.Optional[datetime.datetime] = None,
        finalizers: typing.Optional[typing.Sequence[builtins.str]] = None,
        generate_name: typing.Optional[builtins.str] = None,
        generation: typing.Optional[jsii.Number] = None,
        labels: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        managed_fields: typing.Optional[typing.Sequence[typing.Union[ManagedFieldsEntry, typing.Dict[str, typing.Any]]]] = None,
        name: typing.Optional[builtins.str] = None,
        namespace: typing.Optional[builtins.str] = None,
        owner_references: typing.Optional[typing.Sequence[typing.Union["OwnerReference", typing.Dict[str, typing.Any]]]] = None,
        resource_version: typing.Optional[builtins.str] = None,
        self_link: typing.Optional[builtins.str] = None,
        uid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.

        :param annotations: Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
        :param cluster_name: The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
        :param creation_timestamp: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param deletion_grace_period_seconds: Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
        :param deletion_timestamp: DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested. Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param finalizers: Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
        :param generate_name: GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server. If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header). Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
        :param generation: A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
        :param labels: Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
        :param managed_fields: ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
        :param name: Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
        :param namespace: Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty. Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
        :param owner_references: List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
        :param resource_version: An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources. Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
        :param self_link: SelfLink is a URL representing this object. Populated by the system. Read-only. DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
        :param uid: UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations. Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
        '''
        if __debug__:
            def stub(
                *,
                annotations: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                cluster_name: typing.Optional[builtins.str] = None,
                creation_timestamp: typing.Optional[datetime.datetime] = None,
                deletion_grace_period_seconds: typing.Optional[jsii.Number] = None,
                deletion_timestamp: typing.Optional[datetime.datetime] = None,
                finalizers: typing.Optional[typing.Sequence[builtins.str]] = None,
                generate_name: typing.Optional[builtins.str] = None,
                generation: typing.Optional[jsii.Number] = None,
                labels: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                managed_fields: typing.Optional[typing.Sequence[typing.Union[ManagedFieldsEntry, typing.Dict[str, typing.Any]]]] = None,
                name: typing.Optional[builtins.str] = None,
                namespace: typing.Optional[builtins.str] = None,
                owner_references: typing.Optional[typing.Sequence[typing.Union[OwnerReference, typing.Dict[str, typing.Any]]]] = None,
                resource_version: typing.Optional[builtins.str] = None,
                self_link: typing.Optional[builtins.str] = None,
                uid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument annotations", value=annotations, expected_type=type_hints["annotations"])
            check_type(argname="argument cluster_name", value=cluster_name, expected_type=type_hints["cluster_name"])
            check_type(argname="argument creation_timestamp", value=creation_timestamp, expected_type=type_hints["creation_timestamp"])
            check_type(argname="argument deletion_grace_period_seconds", value=deletion_grace_period_seconds, expected_type=type_hints["deletion_grace_period_seconds"])
            check_type(argname="argument deletion_timestamp", value=deletion_timestamp, expected_type=type_hints["deletion_timestamp"])
            check_type(argname="argument finalizers", value=finalizers, expected_type=type_hints["finalizers"])
            check_type(argname="argument generate_name", value=generate_name, expected_type=type_hints["generate_name"])
            check_type(argname="argument generation", value=generation, expected_type=type_hints["generation"])
            check_type(argname="argument labels", value=labels, expected_type=type_hints["labels"])
            check_type(argname="argument managed_fields", value=managed_fields, expected_type=type_hints["managed_fields"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
            check_type(argname="argument owner_references", value=owner_references, expected_type=type_hints["owner_references"])
            check_type(argname="argument resource_version", value=resource_version, expected_type=type_hints["resource_version"])
            check_type(argname="argument self_link", value=self_link, expected_type=type_hints["self_link"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
        self._values: typing.Dict[str, typing.Any] = {}
        if annotations is not None:
            self._values["annotations"] = annotations
        if cluster_name is not None:
            self._values["cluster_name"] = cluster_name
        if creation_timestamp is not None:
            self._values["creation_timestamp"] = creation_timestamp
        if deletion_grace_period_seconds is not None:
            self._values["deletion_grace_period_seconds"] = deletion_grace_period_seconds
        if deletion_timestamp is not None:
            self._values["deletion_timestamp"] = deletion_timestamp
        if finalizers is not None:
            self._values["finalizers"] = finalizers
        if generate_name is not None:
            self._values["generate_name"] = generate_name
        if generation is not None:
            self._values["generation"] = generation
        if labels is not None:
            self._values["labels"] = labels
        if managed_fields is not None:
            self._values["managed_fields"] = managed_fields
        if name is not None:
            self._values["name"] = name
        if namespace is not None:
            self._values["namespace"] = namespace
        if owner_references is not None:
            self._values["owner_references"] = owner_references
        if resource_version is not None:
            self._values["resource_version"] = resource_version
        if self_link is not None:
            self._values["self_link"] = self_link
        if uid is not None:
            self._values["uid"] = uid

    @builtins.property
    def annotations(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata.

        They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#annotations
        '''
        result = self._values.get("annotations")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def cluster_name(self) -> typing.Optional[builtins.str]:
        '''The name of the cluster which the object belongs to.

        This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#clusterName
        '''
        result = self._values.get("cluster_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def creation_timestamp(self) -> typing.Optional[datetime.datetime]:
        '''CreationTimestamp is a timestamp representing the server time when this object was created.

        It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.

        Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#creationTimestamp
        '''
        result = self._values.get("creation_timestamp")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def deletion_grace_period_seconds(self) -> typing.Optional[jsii.Number]:
        '''Number of seconds allowed for this object to gracefully terminate before it will be removed from the system.

        Only set when deletionTimestamp is also set. May only be shortened. Read-only.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#deletionGracePeriodSeconds
        '''
        result = self._values.get("deletion_grace_period_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def deletion_timestamp(self) -> typing.Optional[datetime.datetime]:
        '''DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted.

        This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.

        Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#deletionTimestamp
        '''
        result = self._values.get("deletion_timestamp")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def finalizers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Must be empty before the object is deleted from the registry.

        Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order.  Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#finalizers
        '''
        result = self._values.get("finalizers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def generate_name(self) -> typing.Optional[builtins.str]:
        '''GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided.

        If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.

        If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).

        Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#generateName
        '''
        result = self._values.get("generate_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def generation(self) -> typing.Optional[jsii.Number]:
        '''A sequence number representing a specific generation of the desired state.

        Populated by the system. Read-only.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#generation
        '''
        result = self._values.get("generation")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def labels(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Map of string keys and values that can be used to organize and categorize (scope and select) objects.

        May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#labels
        '''
        result = self._values.get("labels")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def managed_fields(self) -> typing.Optional[typing.List[ManagedFieldsEntry]]:
        '''ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow.

        This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#managedFields
        '''
        result = self._values.get("managed_fields")
        return typing.cast(typing.Optional[typing.List[ManagedFieldsEntry]], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name must be unique within a namespace.

        Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace defines the space within which each name must be unique.

        An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.

        Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def owner_references(self) -> typing.Optional[typing.List["OwnerReference"]]:
        '''List of objects depended by this object.

        If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#ownerReferences
        '''
        result = self._values.get("owner_references")
        return typing.cast(typing.Optional[typing.List["OwnerReference"]], result)

    @builtins.property
    def resource_version(self) -> typing.Optional[builtins.str]:
        '''An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed.

        May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.

        Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#resourceVersion
        '''
        result = self._values.get("resource_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def self_link(self) -> typing.Optional[builtins.str]:
        '''SelfLink is a URL representing this object. Populated by the system. Read-only.

        DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#selfLink
        '''
        result = self._values.get("self_link")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''UID is the unique in time and space value for this object.

        It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.

        Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ObjectMeta(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ObjectMetricSourceV2",
    jsii_struct_bases=[],
    name_mapping={
        "described_object": "describedObject",
        "metric": "metric",
        "target": "target",
    },
)
class ObjectMetricSourceV2:
    def __init__(
        self,
        *,
        described_object: typing.Union[CrossVersionObjectReferenceV2, typing.Dict[str, typing.Any]],
        metric: typing.Union[MetricIdentifierV2, typing.Dict[str, typing.Any]],
        target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
    ) -> None:
        '''ObjectMetricSource indicates how to scale on a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).

        :param described_object: describedObject specifies the descriptions of a object,such as kind,name apiVersion.
        :param metric: metric identifies the target metric by name and selector.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ObjectMetricSource
        '''
        if isinstance(described_object, dict):
            described_object = CrossVersionObjectReferenceV2(**described_object)
        if isinstance(metric, dict):
            metric = MetricIdentifierV2(**metric)
        if isinstance(target, dict):
            target = MetricTargetV2(**target)
        if __debug__:
            def stub(
                *,
                described_object: typing.Union[CrossVersionObjectReferenceV2, typing.Dict[str, typing.Any]],
                metric: typing.Union[MetricIdentifierV2, typing.Dict[str, typing.Any]],
                target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument described_object", value=described_object, expected_type=type_hints["described_object"])
            check_type(argname="argument metric", value=metric, expected_type=type_hints["metric"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "described_object": described_object,
            "metric": metric,
            "target": target,
        }

    @builtins.property
    def described_object(self) -> CrossVersionObjectReferenceV2:
        '''describedObject specifies the descriptions of a object,such as kind,name apiVersion.

        :schema: io.k8s.api.autoscaling.v2.ObjectMetricSource#describedObject
        '''
        result = self._values.get("described_object")
        assert result is not None, "Required property 'described_object' is missing"
        return typing.cast(CrossVersionObjectReferenceV2, result)

    @builtins.property
    def metric(self) -> MetricIdentifierV2:
        '''metric identifies the target metric by name and selector.

        :schema: io.k8s.api.autoscaling.v2.ObjectMetricSource#metric
        '''
        result = self._values.get("metric")
        assert result is not None, "Required property 'metric' is missing"
        return typing.cast(MetricIdentifierV2, result)

    @builtins.property
    def target(self) -> MetricTargetV2:
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ObjectMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(MetricTargetV2, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ObjectMetricSourceV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ObjectMetricSourceV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "metric_name": "metricName",
        "target": "target",
        "target_value": "targetValue",
        "average_value": "averageValue",
        "selector": "selector",
    },
)
class ObjectMetricSourceV2Beta1:
    def __init__(
        self,
        *,
        metric_name: builtins.str,
        target: typing.Union[CrossVersionObjectReferenceV2Beta1, typing.Dict[str, typing.Any]],
        target_value: "Quantity",
        average_value: typing.Optional["Quantity"] = None,
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ObjectMetricSource indicates how to scale on a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).

        :param metric_name: metricName is the name of the metric in question.
        :param target: target is the described Kubernetes object.
        :param target_value: targetValue is the target value of the metric (as a quantity).
        :param average_value: averageValue is the target value of the average of the metric across all relevant pods (as a quantity).
        :param selector: 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.

        :schema: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource
        '''
        if isinstance(target, dict):
            target = CrossVersionObjectReferenceV2Beta1(**target)
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                metric_name: builtins.str,
                target: typing.Union[CrossVersionObjectReferenceV2Beta1, typing.Dict[str, typing.Any]],
                target_value: Quantity,
                average_value: typing.Optional[Quantity] = None,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric_name", value=metric_name, expected_type=type_hints["metric_name"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
            check_type(argname="argument target_value", value=target_value, expected_type=type_hints["target_value"])
            check_type(argname="argument average_value", value=average_value, expected_type=type_hints["average_value"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric_name": metric_name,
            "target": target,
            "target_value": target_value,
        }
        if average_value is not None:
            self._values["average_value"] = average_value
        if selector is not None:
            self._values["selector"] = selector

    @builtins.property
    def metric_name(self) -> builtins.str:
        '''metricName is the name of the metric in question.

        :schema: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource#metricName
        '''
        result = self._values.get("metric_name")
        assert result is not None, "Required property 'metric_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target(self) -> CrossVersionObjectReferenceV2Beta1:
        '''target is the described Kubernetes object.

        :schema: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(CrossVersionObjectReferenceV2Beta1, result)

    @builtins.property
    def target_value(self) -> "Quantity":
        '''targetValue is the target value of the metric (as a quantity).

        :schema: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource#targetValue
        '''
        result = self._values.get("target_value")
        assert result is not None, "Required property 'target_value' is missing"
        return typing.cast("Quantity", result)

    @builtins.property
    def average_value(self) -> typing.Optional["Quantity"]:
        '''averageValue is the target value of the average of the metric across all relevant pods (as a quantity).

        :schema: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource#averageValue
        '''
        result = self._values.get("average_value")
        return typing.cast(typing.Optional["Quantity"], result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ObjectMetricSourceV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ObjectMetricSourceV2Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "described_object": "describedObject",
        "metric": "metric",
        "target": "target",
    },
)
class ObjectMetricSourceV2Beta2:
    def __init__(
        self,
        *,
        described_object: typing.Union[CrossVersionObjectReferenceV2Beta2, typing.Dict[str, typing.Any]],
        metric: typing.Union[MetricIdentifierV2Beta2, typing.Dict[str, typing.Any]],
        target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
    ) -> None:
        '''ObjectMetricSource indicates how to scale on a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).

        :param described_object: 
        :param metric: metric identifies the target metric by name and selector.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ObjectMetricSource
        '''
        if isinstance(described_object, dict):
            described_object = CrossVersionObjectReferenceV2Beta2(**described_object)
        if isinstance(metric, dict):
            metric = MetricIdentifierV2Beta2(**metric)
        if isinstance(target, dict):
            target = MetricTargetV2Beta2(**target)
        if __debug__:
            def stub(
                *,
                described_object: typing.Union[CrossVersionObjectReferenceV2Beta2, typing.Dict[str, typing.Any]],
                metric: typing.Union[MetricIdentifierV2Beta2, typing.Dict[str, typing.Any]],
                target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument described_object", value=described_object, expected_type=type_hints["described_object"])
            check_type(argname="argument metric", value=metric, expected_type=type_hints["metric"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "described_object": described_object,
            "metric": metric,
            "target": target,
        }

    @builtins.property
    def described_object(self) -> CrossVersionObjectReferenceV2Beta2:
        '''
        :schema: io.k8s.api.autoscaling.v2beta2.ObjectMetricSource#describedObject
        '''
        result = self._values.get("described_object")
        assert result is not None, "Required property 'described_object' is missing"
        return typing.cast(CrossVersionObjectReferenceV2Beta2, result)

    @builtins.property
    def metric(self) -> MetricIdentifierV2Beta2:
        '''metric identifies the target metric by name and selector.

        :schema: io.k8s.api.autoscaling.v2beta2.ObjectMetricSource#metric
        '''
        result = self._values.get("metric")
        assert result is not None, "Required property 'metric' is missing"
        return typing.cast(MetricIdentifierV2Beta2, result)

    @builtins.property
    def target(self) -> MetricTargetV2Beta2:
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ObjectMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(MetricTargetV2Beta2, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ObjectMetricSourceV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ObjectReference",
    jsii_struct_bases=[],
    name_mapping={
        "api_version": "apiVersion",
        "field_path": "fieldPath",
        "kind": "kind",
        "name": "name",
        "namespace": "namespace",
        "resource_version": "resourceVersion",
        "uid": "uid",
    },
)
class ObjectReference:
    def __init__(
        self,
        *,
        api_version: typing.Optional[builtins.str] = None,
        field_path: typing.Optional[builtins.str] = None,
        kind: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        namespace: typing.Optional[builtins.str] = None,
        resource_version: typing.Optional[builtins.str] = None,
        uid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ObjectReference contains enough information to let you inspect or modify the referred object.

        :param api_version: API version of the referent.
        :param field_path: If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object.
        :param kind: Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param namespace: Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
        :param resource_version: Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
        :param uid: UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids

        :schema: io.k8s.api.core.v1.ObjectReference
        '''
        if __debug__:
            def stub(
                *,
                api_version: typing.Optional[builtins.str] = None,
                field_path: typing.Optional[builtins.str] = None,
                kind: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                namespace: typing.Optional[builtins.str] = None,
                resource_version: typing.Optional[builtins.str] = None,
                uid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
            check_type(argname="argument field_path", value=field_path, expected_type=type_hints["field_path"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
            check_type(argname="argument resource_version", value=resource_version, expected_type=type_hints["resource_version"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
        self._values: typing.Dict[str, typing.Any] = {}
        if api_version is not None:
            self._values["api_version"] = api_version
        if field_path is not None:
            self._values["field_path"] = field_path
        if kind is not None:
            self._values["kind"] = kind
        if name is not None:
            self._values["name"] = name
        if namespace is not None:
            self._values["namespace"] = namespace
        if resource_version is not None:
            self._values["resource_version"] = resource_version
        if uid is not None:
            self._values["uid"] = uid

    @builtins.property
    def api_version(self) -> typing.Optional[builtins.str]:
        '''API version of the referent.

        :schema: io.k8s.api.core.v1.ObjectReference#apiVersion
        '''
        result = self._values.get("api_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def field_path(self) -> typing.Optional[builtins.str]:
        '''If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object.

        :schema: io.k8s.api.core.v1.ObjectReference#fieldPath
        '''
        result = self._values.get("field_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def kind(self) -> typing.Optional[builtins.str]:
        '''Kind of the referent.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.api.core.v1.ObjectReference#kind
        '''
        result = self._values.get("kind")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.ObjectReference#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

        :schema: io.k8s.api.core.v1.ObjectReference#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def resource_version(self) -> typing.Optional[builtins.str]:
        '''Specific resourceVersion to which this reference is made, if any.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency

        :schema: io.k8s.api.core.v1.ObjectReference#resourceVersion
        '''
        result = self._values.get("resource_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''UID of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids

        :schema: io.k8s.api.core.v1.ObjectReference#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ObjectReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Overhead",
    jsii_struct_bases=[],
    name_mapping={"pod_fixed": "podFixed"},
)
class Overhead:
    def __init__(
        self,
        *,
        pod_fixed: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
    ) -> None:
        '''Overhead structure represents the resource overhead associated with running a pod.

        :param pod_fixed: PodFixed represents the fixed resource overhead associated with running a pod.

        :schema: io.k8s.api.node.v1.Overhead
        '''
        if __debug__:
            def stub(
                *,
                pod_fixed: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pod_fixed", value=pod_fixed, expected_type=type_hints["pod_fixed"])
        self._values: typing.Dict[str, typing.Any] = {}
        if pod_fixed is not None:
            self._values["pod_fixed"] = pod_fixed

    @builtins.property
    def pod_fixed(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''PodFixed represents the fixed resource overhead associated with running a pod.

        :schema: io.k8s.api.node.v1.Overhead#podFixed
        '''
        result = self._values.get("pod_fixed")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Overhead(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.OverheadV1Alpha1",
    jsii_struct_bases=[],
    name_mapping={"pod_fixed": "podFixed"},
)
class OverheadV1Alpha1:
    def __init__(
        self,
        *,
        pod_fixed: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
    ) -> None:
        '''Overhead structure represents the resource overhead associated with running a pod.

        :param pod_fixed: PodFixed represents the fixed resource overhead associated with running a pod.

        :schema: io.k8s.api.node.v1alpha1.Overhead
        '''
        if __debug__:
            def stub(
                *,
                pod_fixed: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pod_fixed", value=pod_fixed, expected_type=type_hints["pod_fixed"])
        self._values: typing.Dict[str, typing.Any] = {}
        if pod_fixed is not None:
            self._values["pod_fixed"] = pod_fixed

    @builtins.property
    def pod_fixed(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''PodFixed represents the fixed resource overhead associated with running a pod.

        :schema: io.k8s.api.node.v1alpha1.Overhead#podFixed
        '''
        result = self._values.get("pod_fixed")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OverheadV1Alpha1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.OverheadV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"pod_fixed": "podFixed"},
)
class OverheadV1Beta1:
    def __init__(
        self,
        *,
        pod_fixed: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
    ) -> None:
        '''Overhead structure represents the resource overhead associated with running a pod.

        :param pod_fixed: PodFixed represents the fixed resource overhead associated with running a pod.

        :schema: io.k8s.api.node.v1beta1.Overhead
        '''
        if __debug__:
            def stub(
                *,
                pod_fixed: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pod_fixed", value=pod_fixed, expected_type=type_hints["pod_fixed"])
        self._values: typing.Dict[str, typing.Any] = {}
        if pod_fixed is not None:
            self._values["pod_fixed"] = pod_fixed

    @builtins.property
    def pod_fixed(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''PodFixed represents the fixed resource overhead associated with running a pod.

        :schema: io.k8s.api.node.v1beta1.Overhead#podFixed
        '''
        result = self._values.get("pod_fixed")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OverheadV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.OwnerReference",
    jsii_struct_bases=[],
    name_mapping={
        "api_version": "apiVersion",
        "kind": "kind",
        "name": "name",
        "uid": "uid",
        "block_owner_deletion": "blockOwnerDeletion",
        "controller": "controller",
    },
)
class OwnerReference:
    def __init__(
        self,
        *,
        api_version: builtins.str,
        kind: builtins.str,
        name: builtins.str,
        uid: builtins.str,
        block_owner_deletion: typing.Optional[builtins.bool] = None,
        controller: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''OwnerReference contains enough information to let you identify an owning object.

        An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.

        :param api_version: API version of the referent.
        :param kind: Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        :param name: Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names
        :param uid: UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
        :param block_owner_deletion: If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned. Default: false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.
        :param controller: If true, this reference points to the managing controller.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference
        '''
        if __debug__:
            def stub(
                *,
                api_version: builtins.str,
                kind: builtins.str,
                name: builtins.str,
                uid: builtins.str,
                block_owner_deletion: typing.Optional[builtins.bool] = None,
                controller: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_version", value=api_version, expected_type=type_hints["api_version"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
            check_type(argname="argument block_owner_deletion", value=block_owner_deletion, expected_type=type_hints["block_owner_deletion"])
            check_type(argname="argument controller", value=controller, expected_type=type_hints["controller"])
        self._values: typing.Dict[str, typing.Any] = {
            "api_version": api_version,
            "kind": kind,
            "name": name,
            "uid": uid,
        }
        if block_owner_deletion is not None:
            self._values["block_owner_deletion"] = block_owner_deletion
        if controller is not None:
            self._values["controller"] = controller

    @builtins.property
    def api_version(self) -> builtins.str:
        '''API version of the referent.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference#apiVersion
        '''
        result = self._values.get("api_version")
        assert result is not None, "Required property 'api_version' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind of the referent.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the referent.

        More info: http://kubernetes.io/docs/user-guide/identifiers#names

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def uid(self) -> builtins.str:
        '''UID of the referent.

        More info: http://kubernetes.io/docs/user-guide/identifiers#uids

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference#uid
        '''
        result = self._values.get("uid")
        assert result is not None, "Required property 'uid' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def block_owner_deletion(self) -> typing.Optional[builtins.bool]:
        '''If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed.

        Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.

        :default: false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference#blockOwnerDeletion
        '''
        result = self._values.get("block_owner_deletion")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def controller(self) -> typing.Optional[builtins.bool]:
        '''If true, this reference points to the managing controller.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference#controller
        '''
        result = self._values.get("controller")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OwnerReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PersistentVolumeClaimSpec",
    jsii_struct_bases=[],
    name_mapping={
        "access_modes": "accessModes",
        "data_source": "dataSource",
        "data_source_ref": "dataSourceRef",
        "resources": "resources",
        "selector": "selector",
        "storage_class_name": "storageClassName",
        "volume_mode": "volumeMode",
        "volume_name": "volumeName",
    },
)
class PersistentVolumeClaimSpec:
    def __init__(
        self,
        *,
        access_modes: typing.Optional[typing.Sequence[builtins.str]] = None,
        data_source: typing.Optional[typing.Union["TypedLocalObjectReference", typing.Dict[str, typing.Any]]] = None,
        data_source_ref: typing.Optional[typing.Union["TypedLocalObjectReference", typing.Dict[str, typing.Any]]] = None,
        resources: typing.Optional[typing.Union["ResourceRequirements", typing.Dict[str, typing.Any]]] = None,
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        storage_class_name: typing.Optional[builtins.str] = None,
        volume_mode: typing.Optional[builtins.str] = None,
        volume_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''PersistentVolumeClaimSpec describes the common attributes of storage devices and allows a Source for provider-specific attributes.

        :param access_modes: AccessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
        :param data_source: This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the AnyVolumeDataSource feature gate is enabled, this field will always have the same contents as the DataSourceRef field.
        :param data_source_ref: Specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any local object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the DataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, both fields (DataSource and DataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. There are two important differences between DataSource and DataSourceRef: * While DataSource only allows two specific types of objects, DataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. - While DataSource ignores disallowed values (dropping them), DataSourceRef preserves all values, and generates an error if a disallowed value is specified. (Alpha) Using this field requires the AnyVolumeDataSource feature gate to be enabled.
        :param resources: Resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
        :param selector: A label query over volumes to consider for binding.
        :param storage_class_name: Name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
        :param volume_mode: volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.
        :param volume_name: VolumeName is the binding reference to the PersistentVolume backing this claim.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec
        '''
        if isinstance(data_source, dict):
            data_source = TypedLocalObjectReference(**data_source)
        if isinstance(data_source_ref, dict):
            data_source_ref = TypedLocalObjectReference(**data_source_ref)
        if isinstance(resources, dict):
            resources = ResourceRequirements(**resources)
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                access_modes: typing.Optional[typing.Sequence[builtins.str]] = None,
                data_source: typing.Optional[typing.Union[TypedLocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                data_source_ref: typing.Optional[typing.Union[TypedLocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                resources: typing.Optional[typing.Union[ResourceRequirements, typing.Dict[str, typing.Any]]] = None,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                storage_class_name: typing.Optional[builtins.str] = None,
                volume_mode: typing.Optional[builtins.str] = None,
                volume_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument access_modes", value=access_modes, expected_type=type_hints["access_modes"])
            check_type(argname="argument data_source", value=data_source, expected_type=type_hints["data_source"])
            check_type(argname="argument data_source_ref", value=data_source_ref, expected_type=type_hints["data_source_ref"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument storage_class_name", value=storage_class_name, expected_type=type_hints["storage_class_name"])
            check_type(argname="argument volume_mode", value=volume_mode, expected_type=type_hints["volume_mode"])
            check_type(argname="argument volume_name", value=volume_name, expected_type=type_hints["volume_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if access_modes is not None:
            self._values["access_modes"] = access_modes
        if data_source is not None:
            self._values["data_source"] = data_source
        if data_source_ref is not None:
            self._values["data_source_ref"] = data_source_ref
        if resources is not None:
            self._values["resources"] = resources
        if selector is not None:
            self._values["selector"] = selector
        if storage_class_name is not None:
            self._values["storage_class_name"] = storage_class_name
        if volume_mode is not None:
            self._values["volume_mode"] = volume_mode
        if volume_name is not None:
            self._values["volume_name"] = volume_name

    @builtins.property
    def access_modes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''AccessModes contains the desired access modes the volume should have.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#accessModes
        '''
        result = self._values.get("access_modes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def data_source(self) -> typing.Optional["TypedLocalObjectReference"]:
        '''This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the AnyVolumeDataSource feature gate is enabled, this field will always have the same contents as the DataSourceRef field.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#dataSource
        '''
        result = self._values.get("data_source")
        return typing.cast(typing.Optional["TypedLocalObjectReference"], result)

    @builtins.property
    def data_source_ref(self) -> typing.Optional["TypedLocalObjectReference"]:
        '''Specifies the object from which to populate the volume with data, if a non-empty volume is desired.

        This may be any local object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the DataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, both fields (DataSource and DataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. There are two important differences between DataSource and DataSourceRef: * While DataSource only allows two specific types of objects, DataSourceRef
        allows any non-core object, as well as PersistentVolumeClaim objects.

        - While DataSource ignores disallowed values (dropping them), DataSourceRef
          preserves all values, and generates an error if a disallowed value is
          specified.
          (Alpha) Using this field requires the AnyVolumeDataSource feature gate to be enabled.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#dataSourceRef
        '''
        result = self._values.get("data_source_ref")
        return typing.cast(typing.Optional["TypedLocalObjectReference"], result)

    @builtins.property
    def resources(self) -> typing.Optional["ResourceRequirements"]:
        '''Resources represents the minimum resources the volume should have.

        If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#resources
        '''
        result = self._values.get("resources")
        return typing.cast(typing.Optional["ResourceRequirements"], result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''A label query over volumes to consider for binding.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def storage_class_name(self) -> typing.Optional[builtins.str]:
        '''Name of the StorageClass required by the claim.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#storageClassName
        '''
        result = self._values.get("storage_class_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_mode(self) -> typing.Optional[builtins.str]:
        '''volumeMode defines what type of volume is required by the claim.

        Value of Filesystem is implied when not included in claim spec.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#volumeMode
        '''
        result = self._values.get("volume_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_name(self) -> typing.Optional[builtins.str]:
        '''VolumeName is the binding reference to the PersistentVolume backing this claim.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimSpec#volumeName
        '''
        result = self._values.get("volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PersistentVolumeClaimSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PersistentVolumeClaimTemplate",
    jsii_struct_bases=[],
    name_mapping={"spec": "spec", "metadata": "metadata"},
)
class PersistentVolumeClaimTemplate:
    def __init__(
        self,
        *,
        spec: typing.Union[PersistentVolumeClaimSpec, typing.Dict[str, typing.Any]],
        metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PersistentVolumeClaimTemplate is used to produce PersistentVolumeClaim objects as part of an EphemeralVolumeSource.

        :param spec: The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here.
        :param metadata: May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimTemplate
        '''
        if isinstance(spec, dict):
            spec = PersistentVolumeClaimSpec(**spec)
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if __debug__:
            def stub(
                *,
                spec: typing.Union[PersistentVolumeClaimSpec, typing.Dict[str, typing.Any]],
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
        self._values: typing.Dict[str, typing.Any] = {
            "spec": spec,
        }
        if metadata is not None:
            self._values["metadata"] = metadata

    @builtins.property
    def spec(self) -> PersistentVolumeClaimSpec:
        '''The specification for the PersistentVolumeClaim.

        The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimTemplate#spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(PersistentVolumeClaimSpec, result)

    @builtins.property
    def metadata(self) -> typing.Optional[ObjectMeta]:
        '''May contain labels and annotations that will be copied into the PVC when creating it.

        No other fields are allowed and will be rejected during validation.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimTemplate#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional[ObjectMeta], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PersistentVolumeClaimTemplate(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PersistentVolumeClaimVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"claim_name": "claimName", "read_only": "readOnly"},
)
class PersistentVolumeClaimVolumeSource:
    def __init__(
        self,
        *,
        claim_name: builtins.str,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace.

        This volume finds the bound PV and mounts that volume for the pod. A PersistentVolumeClaimVolumeSource is, essentially, a wrapper around another type of volume that is owned by someone else (the system).

        :param claim_name: ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        :param read_only: Will force the ReadOnly setting in VolumeMounts. Default false.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                claim_name: builtins.str,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument claim_name", value=claim_name, expected_type=type_hints["claim_name"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "claim_name": claim_name,
        }
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def claim_name(self) -> builtins.str:
        '''ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimVolumeSource#claimName
        '''
        result = self._values.get("claim_name")
        assert result is not None, "Required property 'claim_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Will force the ReadOnly setting in VolumeMounts.

        Default false.

        :schema: io.k8s.api.core.v1.PersistentVolumeClaimVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PersistentVolumeClaimVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PersistentVolumeSpec",
    jsii_struct_bases=[],
    name_mapping={
        "access_modes": "accessModes",
        "aws_elastic_block_store": "awsElasticBlockStore",
        "azure_disk": "azureDisk",
        "azure_file": "azureFile",
        "capacity": "capacity",
        "cephfs": "cephfs",
        "cinder": "cinder",
        "claim_ref": "claimRef",
        "csi": "csi",
        "fc": "fc",
        "flex_volume": "flexVolume",
        "flocker": "flocker",
        "gce_persistent_disk": "gcePersistentDisk",
        "glusterfs": "glusterfs",
        "host_path": "hostPath",
        "iscsi": "iscsi",
        "local": "local",
        "mount_options": "mountOptions",
        "nfs": "nfs",
        "node_affinity": "nodeAffinity",
        "persistent_volume_reclaim_policy": "persistentVolumeReclaimPolicy",
        "photon_persistent_disk": "photonPersistentDisk",
        "portworx_volume": "portworxVolume",
        "quobyte": "quobyte",
        "rbd": "rbd",
        "scale_io": "scaleIo",
        "storage_class_name": "storageClassName",
        "storageos": "storageos",
        "volume_mode": "volumeMode",
        "vsphere_volume": "vsphereVolume",
    },
)
class PersistentVolumeSpec:
    def __init__(
        self,
        *,
        access_modes: typing.Optional[typing.Sequence[builtins.str]] = None,
        aws_elastic_block_store: typing.Optional[typing.Union[AwsElasticBlockStoreVolumeSource, typing.Dict[str, typing.Any]]] = None,
        azure_disk: typing.Optional[typing.Union[AzureDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
        azure_file: typing.Optional[typing.Union[AzureFilePersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        capacity: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
        cephfs: typing.Optional[typing.Union[CephFsPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        cinder: typing.Optional[typing.Union[CinderPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        claim_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
        csi: typing.Optional[typing.Union[CsiPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        fc: typing.Optional[typing.Union[FcVolumeSource, typing.Dict[str, typing.Any]]] = None,
        flex_volume: typing.Optional[typing.Union[FlexPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        flocker: typing.Optional[typing.Union[FlockerVolumeSource, typing.Dict[str, typing.Any]]] = None,
        gce_persistent_disk: typing.Optional[typing.Union[GcePersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
        glusterfs: typing.Optional[typing.Union[GlusterfsPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        host_path: typing.Optional[typing.Union[HostPathVolumeSource, typing.Dict[str, typing.Any]]] = None,
        iscsi: typing.Optional[typing.Union[IscsiPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
        local: typing.Optional[typing.Union[LocalVolumeSource, typing.Dict[str, typing.Any]]] = None,
        mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
        nfs: typing.Optional[typing.Union[NfsVolumeSource, typing.Dict[str, typing.Any]]] = None,
        node_affinity: typing.Optional[typing.Union["VolumeNodeAffinity", typing.Dict[str, typing.Any]]] = None,
        persistent_volume_reclaim_policy: typing.Optional[IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy] = None,
        photon_persistent_disk: typing.Optional[typing.Union["PhotonPersistentDiskVolumeSource", typing.Dict[str, typing.Any]]] = None,
        portworx_volume: typing.Optional[typing.Union["PortworxVolumeSource", typing.Dict[str, typing.Any]]] = None,
        quobyte: typing.Optional[typing.Union["QuobyteVolumeSource", typing.Dict[str, typing.Any]]] = None,
        rbd: typing.Optional[typing.Union["RbdPersistentVolumeSource", typing.Dict[str, typing.Any]]] = None,
        scale_io: typing.Optional[typing.Union["ScaleIoPersistentVolumeSource", typing.Dict[str, typing.Any]]] = None,
        storage_class_name: typing.Optional[builtins.str] = None,
        storageos: typing.Optional[typing.Union["StorageOsPersistentVolumeSource", typing.Dict[str, typing.Any]]] = None,
        volume_mode: typing.Optional[builtins.str] = None,
        vsphere_volume: typing.Optional[typing.Union["VsphereVirtualDiskVolumeSource", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PersistentVolumeSpec is the specification of a persistent volume.

        :param access_modes: AccessModes contains all ways the volume can be mounted. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes
        :param aws_elastic_block_store: AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
        :param azure_disk: AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
        :param azure_file: AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
        :param capacity: A description of the persistent volume's resources and capacity. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#capacity
        :param cephfs: CephFS represents a Ceph FS mount on the host that shares a pod's lifetime.
        :param cinder: Cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param claim_ref: ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. Expected to be non-nil when bound. claim.VolumeName is the authoritative bind between PV and PVC. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#binding
        :param csi: CSI represents storage that is handled by an external CSI driver (Beta feature).
        :param fc: FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.
        :param flex_volume: FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.
        :param flocker: Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running
        :param gce_persistent_disk: GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
        :param glusterfs: Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod. Provisioned by an admin. More info: https://examples.k8s.io/volumes/glusterfs/README.md
        :param host_path: HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for single-node development and testing only! On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
        :param iscsi: ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin.
        :param local: Local represents directly-attached storage with node affinity.
        :param mount_options: A list of mount options, e.g. ["ro", "soft"]. Not validated - mount will simply fail if one is invalid. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#mount-options.
        :param nfs: NFS represents an NFS mount on the host. Provisioned by an admin. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
        :param node_affinity: NodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume.
        :param persistent_volume_reclaim_policy: What happens to a persistent volume when released from its claim. Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming Possible enum values: - ``"Delete"`` means the volume will be deleted from Kubernetes on release from its claim. The volume plugin must support Deletion. - ``"Recycle"`` means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. The volume plugin must support Recycling. - ``"Retain"`` means the volume will be left in its current phase (Released) for manual reclamation by the administrator. The default policy is Retain.
        :param photon_persistent_disk: PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.
        :param portworx_volume: PortworxVolume represents a portworx volume attached and mounted on kubelets host machine.
        :param quobyte: Quobyte represents a Quobyte mount on the host that shares a pod's lifetime.
        :param rbd: RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md
        :param scale_io: ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
        :param storage_class_name: Name of StorageClass to which this persistent volume belongs. Empty value means that this volume does not belong to any StorageClass.
        :param storageos: StorageOS represents a StorageOS volume that is attached to the kubelet's host machine and mounted into the pod More info: https://examples.k8s.io/volumes/storageos/README.md.
        :param volume_mode: volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state. Value of Filesystem is implied when not included in spec.
        :param vsphere_volume: VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec
        '''
        if isinstance(aws_elastic_block_store, dict):
            aws_elastic_block_store = AwsElasticBlockStoreVolumeSource(**aws_elastic_block_store)
        if isinstance(azure_disk, dict):
            azure_disk = AzureDiskVolumeSource(**azure_disk)
        if isinstance(azure_file, dict):
            azure_file = AzureFilePersistentVolumeSource(**azure_file)
        if isinstance(cephfs, dict):
            cephfs = CephFsPersistentVolumeSource(**cephfs)
        if isinstance(cinder, dict):
            cinder = CinderPersistentVolumeSource(**cinder)
        if isinstance(claim_ref, dict):
            claim_ref = ObjectReference(**claim_ref)
        if isinstance(csi, dict):
            csi = CsiPersistentVolumeSource(**csi)
        if isinstance(fc, dict):
            fc = FcVolumeSource(**fc)
        if isinstance(flex_volume, dict):
            flex_volume = FlexPersistentVolumeSource(**flex_volume)
        if isinstance(flocker, dict):
            flocker = FlockerVolumeSource(**flocker)
        if isinstance(gce_persistent_disk, dict):
            gce_persistent_disk = GcePersistentDiskVolumeSource(**gce_persistent_disk)
        if isinstance(glusterfs, dict):
            glusterfs = GlusterfsPersistentVolumeSource(**glusterfs)
        if isinstance(host_path, dict):
            host_path = HostPathVolumeSource(**host_path)
        if isinstance(iscsi, dict):
            iscsi = IscsiPersistentVolumeSource(**iscsi)
        if isinstance(local, dict):
            local = LocalVolumeSource(**local)
        if isinstance(nfs, dict):
            nfs = NfsVolumeSource(**nfs)
        if isinstance(node_affinity, dict):
            node_affinity = VolumeNodeAffinity(**node_affinity)
        if isinstance(photon_persistent_disk, dict):
            photon_persistent_disk = PhotonPersistentDiskVolumeSource(**photon_persistent_disk)
        if isinstance(portworx_volume, dict):
            portworx_volume = PortworxVolumeSource(**portworx_volume)
        if isinstance(quobyte, dict):
            quobyte = QuobyteVolumeSource(**quobyte)
        if isinstance(rbd, dict):
            rbd = RbdPersistentVolumeSource(**rbd)
        if isinstance(scale_io, dict):
            scale_io = ScaleIoPersistentVolumeSource(**scale_io)
        if isinstance(storageos, dict):
            storageos = StorageOsPersistentVolumeSource(**storageos)
        if isinstance(vsphere_volume, dict):
            vsphere_volume = VsphereVirtualDiskVolumeSource(**vsphere_volume)
        if __debug__:
            def stub(
                *,
                access_modes: typing.Optional[typing.Sequence[builtins.str]] = None,
                aws_elastic_block_store: typing.Optional[typing.Union[AwsElasticBlockStoreVolumeSource, typing.Dict[str, typing.Any]]] = None,
                azure_disk: typing.Optional[typing.Union[AzureDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
                azure_file: typing.Optional[typing.Union[AzureFilePersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                capacity: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                cephfs: typing.Optional[typing.Union[CephFsPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                cinder: typing.Optional[typing.Union[CinderPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                claim_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                csi: typing.Optional[typing.Union[CsiPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                fc: typing.Optional[typing.Union[FcVolumeSource, typing.Dict[str, typing.Any]]] = None,
                flex_volume: typing.Optional[typing.Union[FlexPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                flocker: typing.Optional[typing.Union[FlockerVolumeSource, typing.Dict[str, typing.Any]]] = None,
                gce_persistent_disk: typing.Optional[typing.Union[GcePersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
                glusterfs: typing.Optional[typing.Union[GlusterfsPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                host_path: typing.Optional[typing.Union[HostPathVolumeSource, typing.Dict[str, typing.Any]]] = None,
                iscsi: typing.Optional[typing.Union[IscsiPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                local: typing.Optional[typing.Union[LocalVolumeSource, typing.Dict[str, typing.Any]]] = None,
                mount_options: typing.Optional[typing.Sequence[builtins.str]] = None,
                nfs: typing.Optional[typing.Union[NfsVolumeSource, typing.Dict[str, typing.Any]]] = None,
                node_affinity: typing.Optional[typing.Union[VolumeNodeAffinity, typing.Dict[str, typing.Any]]] = None,
                persistent_volume_reclaim_policy: typing.Optional[IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy] = None,
                photon_persistent_disk: typing.Optional[typing.Union[PhotonPersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
                portworx_volume: typing.Optional[typing.Union[PortworxVolumeSource, typing.Dict[str, typing.Any]]] = None,
                quobyte: typing.Optional[typing.Union[QuobyteVolumeSource, typing.Dict[str, typing.Any]]] = None,
                rbd: typing.Optional[typing.Union[RbdPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                scale_io: typing.Optional[typing.Union[ScaleIoPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                storage_class_name: typing.Optional[builtins.str] = None,
                storageos: typing.Optional[typing.Union[StorageOsPersistentVolumeSource, typing.Dict[str, typing.Any]]] = None,
                volume_mode: typing.Optional[builtins.str] = None,
                vsphere_volume: typing.Optional[typing.Union[VsphereVirtualDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument access_modes", value=access_modes, expected_type=type_hints["access_modes"])
            check_type(argname="argument aws_elastic_block_store", value=aws_elastic_block_store, expected_type=type_hints["aws_elastic_block_store"])
            check_type(argname="argument azure_disk", value=azure_disk, expected_type=type_hints["azure_disk"])
            check_type(argname="argument azure_file", value=azure_file, expected_type=type_hints["azure_file"])
            check_type(argname="argument capacity", value=capacity, expected_type=type_hints["capacity"])
            check_type(argname="argument cephfs", value=cephfs, expected_type=type_hints["cephfs"])
            check_type(argname="argument cinder", value=cinder, expected_type=type_hints["cinder"])
            check_type(argname="argument claim_ref", value=claim_ref, expected_type=type_hints["claim_ref"])
            check_type(argname="argument csi", value=csi, expected_type=type_hints["csi"])
            check_type(argname="argument fc", value=fc, expected_type=type_hints["fc"])
            check_type(argname="argument flex_volume", value=flex_volume, expected_type=type_hints["flex_volume"])
            check_type(argname="argument flocker", value=flocker, expected_type=type_hints["flocker"])
            check_type(argname="argument gce_persistent_disk", value=gce_persistent_disk, expected_type=type_hints["gce_persistent_disk"])
            check_type(argname="argument glusterfs", value=glusterfs, expected_type=type_hints["glusterfs"])
            check_type(argname="argument host_path", value=host_path, expected_type=type_hints["host_path"])
            check_type(argname="argument iscsi", value=iscsi, expected_type=type_hints["iscsi"])
            check_type(argname="argument local", value=local, expected_type=type_hints["local"])
            check_type(argname="argument mount_options", value=mount_options, expected_type=type_hints["mount_options"])
            check_type(argname="argument nfs", value=nfs, expected_type=type_hints["nfs"])
            check_type(argname="argument node_affinity", value=node_affinity, expected_type=type_hints["node_affinity"])
            check_type(argname="argument persistent_volume_reclaim_policy", value=persistent_volume_reclaim_policy, expected_type=type_hints["persistent_volume_reclaim_policy"])
            check_type(argname="argument photon_persistent_disk", value=photon_persistent_disk, expected_type=type_hints["photon_persistent_disk"])
            check_type(argname="argument portworx_volume", value=portworx_volume, expected_type=type_hints["portworx_volume"])
            check_type(argname="argument quobyte", value=quobyte, expected_type=type_hints["quobyte"])
            check_type(argname="argument rbd", value=rbd, expected_type=type_hints["rbd"])
            check_type(argname="argument scale_io", value=scale_io, expected_type=type_hints["scale_io"])
            check_type(argname="argument storage_class_name", value=storage_class_name, expected_type=type_hints["storage_class_name"])
            check_type(argname="argument storageos", value=storageos, expected_type=type_hints["storageos"])
            check_type(argname="argument volume_mode", value=volume_mode, expected_type=type_hints["volume_mode"])
            check_type(argname="argument vsphere_volume", value=vsphere_volume, expected_type=type_hints["vsphere_volume"])
        self._values: typing.Dict[str, typing.Any] = {}
        if access_modes is not None:
            self._values["access_modes"] = access_modes
        if aws_elastic_block_store is not None:
            self._values["aws_elastic_block_store"] = aws_elastic_block_store
        if azure_disk is not None:
            self._values["azure_disk"] = azure_disk
        if azure_file is not None:
            self._values["azure_file"] = azure_file
        if capacity is not None:
            self._values["capacity"] = capacity
        if cephfs is not None:
            self._values["cephfs"] = cephfs
        if cinder is not None:
            self._values["cinder"] = cinder
        if claim_ref is not None:
            self._values["claim_ref"] = claim_ref
        if csi is not None:
            self._values["csi"] = csi
        if fc is not None:
            self._values["fc"] = fc
        if flex_volume is not None:
            self._values["flex_volume"] = flex_volume
        if flocker is not None:
            self._values["flocker"] = flocker
        if gce_persistent_disk is not None:
            self._values["gce_persistent_disk"] = gce_persistent_disk
        if glusterfs is not None:
            self._values["glusterfs"] = glusterfs
        if host_path is not None:
            self._values["host_path"] = host_path
        if iscsi is not None:
            self._values["iscsi"] = iscsi
        if local is not None:
            self._values["local"] = local
        if mount_options is not None:
            self._values["mount_options"] = mount_options
        if nfs is not None:
            self._values["nfs"] = nfs
        if node_affinity is not None:
            self._values["node_affinity"] = node_affinity
        if persistent_volume_reclaim_policy is not None:
            self._values["persistent_volume_reclaim_policy"] = persistent_volume_reclaim_policy
        if photon_persistent_disk is not None:
            self._values["photon_persistent_disk"] = photon_persistent_disk
        if portworx_volume is not None:
            self._values["portworx_volume"] = portworx_volume
        if quobyte is not None:
            self._values["quobyte"] = quobyte
        if rbd is not None:
            self._values["rbd"] = rbd
        if scale_io is not None:
            self._values["scale_io"] = scale_io
        if storage_class_name is not None:
            self._values["storage_class_name"] = storage_class_name
        if storageos is not None:
            self._values["storageos"] = storageos
        if volume_mode is not None:
            self._values["volume_mode"] = volume_mode
        if vsphere_volume is not None:
            self._values["vsphere_volume"] = vsphere_volume

    @builtins.property
    def access_modes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''AccessModes contains all ways the volume can be mounted.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#accessModes
        '''
        result = self._values.get("access_modes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def aws_elastic_block_store(
        self,
    ) -> typing.Optional[AwsElasticBlockStoreVolumeSource]:
        '''AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#awsElasticBlockStore
        '''
        result = self._values.get("aws_elastic_block_store")
        return typing.cast(typing.Optional[AwsElasticBlockStoreVolumeSource], result)

    @builtins.property
    def azure_disk(self) -> typing.Optional[AzureDiskVolumeSource]:
        '''AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#azureDisk
        '''
        result = self._values.get("azure_disk")
        return typing.cast(typing.Optional[AzureDiskVolumeSource], result)

    @builtins.property
    def azure_file(self) -> typing.Optional[AzureFilePersistentVolumeSource]:
        '''AzureFile represents an Azure File Service mount on the host and bind mount to the pod.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#azureFile
        '''
        result = self._values.get("azure_file")
        return typing.cast(typing.Optional[AzureFilePersistentVolumeSource], result)

    @builtins.property
    def capacity(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''A description of the persistent volume's resources and capacity.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#capacity

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#capacity
        '''
        result = self._values.get("capacity")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    @builtins.property
    def cephfs(self) -> typing.Optional[CephFsPersistentVolumeSource]:
        '''CephFS represents a Ceph FS mount on the host that shares a pod's lifetime.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#cephfs
        '''
        result = self._values.get("cephfs")
        return typing.cast(typing.Optional[CephFsPersistentVolumeSource], result)

    @builtins.property
    def cinder(self) -> typing.Optional[CinderPersistentVolumeSource]:
        '''Cinder represents a cinder volume attached and mounted on kubelets host machine.

        More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#cinder
        '''
        result = self._values.get("cinder")
        return typing.cast(typing.Optional[CinderPersistentVolumeSource], result)

    @builtins.property
    def claim_ref(self) -> typing.Optional[ObjectReference]:
        '''ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim.

        Expected to be non-nil when bound. claim.VolumeName is the authoritative bind between PV and PVC. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#binding

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#claimRef
        '''
        result = self._values.get("claim_ref")
        return typing.cast(typing.Optional[ObjectReference], result)

    @builtins.property
    def csi(self) -> typing.Optional[CsiPersistentVolumeSource]:
        '''CSI represents storage that is handled by an external CSI driver (Beta feature).

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#csi
        '''
        result = self._values.get("csi")
        return typing.cast(typing.Optional[CsiPersistentVolumeSource], result)

    @builtins.property
    def fc(self) -> typing.Optional[FcVolumeSource]:
        '''FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#fc
        '''
        result = self._values.get("fc")
        return typing.cast(typing.Optional[FcVolumeSource], result)

    @builtins.property
    def flex_volume(self) -> typing.Optional[FlexPersistentVolumeSource]:
        '''FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#flexVolume
        '''
        result = self._values.get("flex_volume")
        return typing.cast(typing.Optional[FlexPersistentVolumeSource], result)

    @builtins.property
    def flocker(self) -> typing.Optional[FlockerVolumeSource]:
        '''Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage.

        This depends on the Flocker control service being running

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#flocker
        '''
        result = self._values.get("flocker")
        return typing.cast(typing.Optional[FlockerVolumeSource], result)

    @builtins.property
    def gce_persistent_disk(self) -> typing.Optional[GcePersistentDiskVolumeSource]:
        '''GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod.

        Provisioned by an admin. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#gcePersistentDisk
        '''
        result = self._values.get("gce_persistent_disk")
        return typing.cast(typing.Optional[GcePersistentDiskVolumeSource], result)

    @builtins.property
    def glusterfs(self) -> typing.Optional[GlusterfsPersistentVolumeSource]:
        '''Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod.

        Provisioned by an admin. More info: https://examples.k8s.io/volumes/glusterfs/README.md

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#glusterfs
        '''
        result = self._values.get("glusterfs")
        return typing.cast(typing.Optional[GlusterfsPersistentVolumeSource], result)

    @builtins.property
    def host_path(self) -> typing.Optional[HostPathVolumeSource]:
        '''HostPath represents a directory on the host.

        Provisioned by a developer or tester. This is useful for single-node development and testing only! On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#hostPath
        '''
        result = self._values.get("host_path")
        return typing.cast(typing.Optional[HostPathVolumeSource], result)

    @builtins.property
    def iscsi(self) -> typing.Optional[IscsiPersistentVolumeSource]:
        '''ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod.

        Provisioned by an admin.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#iscsi
        '''
        result = self._values.get("iscsi")
        return typing.cast(typing.Optional[IscsiPersistentVolumeSource], result)

    @builtins.property
    def local(self) -> typing.Optional[LocalVolumeSource]:
        '''Local represents directly-attached storage with node affinity.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#local
        '''
        result = self._values.get("local")
        return typing.cast(typing.Optional[LocalVolumeSource], result)

    @builtins.property
    def mount_options(self) -> typing.Optional[typing.List[builtins.str]]:
        '''A list of mount options, e.g. ["ro", "soft"]. Not validated - mount will simply fail if one is invalid. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#mount-options.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#mountOptions
        '''
        result = self._values.get("mount_options")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def nfs(self) -> typing.Optional[NfsVolumeSource]:
        '''NFS represents an NFS mount on the host.

        Provisioned by an admin. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#nfs
        '''
        result = self._values.get("nfs")
        return typing.cast(typing.Optional[NfsVolumeSource], result)

    @builtins.property
    def node_affinity(self) -> typing.Optional["VolumeNodeAffinity"]:
        '''NodeAffinity defines constraints that limit what nodes this volume can be accessed from.

        This field influences the scheduling of pods that use this volume.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#nodeAffinity
        '''
        result = self._values.get("node_affinity")
        return typing.cast(typing.Optional["VolumeNodeAffinity"], result)

    @builtins.property
    def persistent_volume_reclaim_policy(
        self,
    ) -> typing.Optional[IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy]:
        '''What happens to a persistent volume when released from its claim.

        Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming

        Possible enum values:

        - ``"Delete"`` means the volume will be deleted from Kubernetes on release from its claim. The volume plugin must support Deletion.
        - ``"Recycle"`` means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. The volume plugin must support Recycling.
        - ``"Retain"`` means the volume will be left in its current phase (Released) for manual reclamation by the administrator. The default policy is Retain.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#persistentVolumeReclaimPolicy
        '''
        result = self._values.get("persistent_volume_reclaim_policy")
        return typing.cast(typing.Optional[IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy], result)

    @builtins.property
    def photon_persistent_disk(
        self,
    ) -> typing.Optional["PhotonPersistentDiskVolumeSource"]:
        '''PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#photonPersistentDisk
        '''
        result = self._values.get("photon_persistent_disk")
        return typing.cast(typing.Optional["PhotonPersistentDiskVolumeSource"], result)

    @builtins.property
    def portworx_volume(self) -> typing.Optional["PortworxVolumeSource"]:
        '''PortworxVolume represents a portworx volume attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#portworxVolume
        '''
        result = self._values.get("portworx_volume")
        return typing.cast(typing.Optional["PortworxVolumeSource"], result)

    @builtins.property
    def quobyte(self) -> typing.Optional["QuobyteVolumeSource"]:
        '''Quobyte represents a Quobyte mount on the host that shares a pod's lifetime.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#quobyte
        '''
        result = self._values.get("quobyte")
        return typing.cast(typing.Optional["QuobyteVolumeSource"], result)

    @builtins.property
    def rbd(self) -> typing.Optional["RbdPersistentVolumeSource"]:
        '''RBD represents a Rados Block Device mount on the host that shares a pod's lifetime.

        More info: https://examples.k8s.io/volumes/rbd/README.md

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#rbd
        '''
        result = self._values.get("rbd")
        return typing.cast(typing.Optional["RbdPersistentVolumeSource"], result)

    @builtins.property
    def scale_io(self) -> typing.Optional["ScaleIoPersistentVolumeSource"]:
        '''ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#scaleIO
        '''
        result = self._values.get("scale_io")
        return typing.cast(typing.Optional["ScaleIoPersistentVolumeSource"], result)

    @builtins.property
    def storage_class_name(self) -> typing.Optional[builtins.str]:
        '''Name of StorageClass to which this persistent volume belongs.

        Empty value means that this volume does not belong to any StorageClass.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#storageClassName
        '''
        result = self._values.get("storage_class_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def storageos(self) -> typing.Optional["StorageOsPersistentVolumeSource"]:
        '''StorageOS represents a StorageOS volume that is attached to the kubelet's host machine and mounted into the pod More info: https://examples.k8s.io/volumes/storageos/README.md.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#storageos
        '''
        result = self._values.get("storageos")
        return typing.cast(typing.Optional["StorageOsPersistentVolumeSource"], result)

    @builtins.property
    def volume_mode(self) -> typing.Optional[builtins.str]:
        '''volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state.

        Value of Filesystem is implied when not included in spec.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#volumeMode
        '''
        result = self._values.get("volume_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vsphere_volume(self) -> typing.Optional["VsphereVirtualDiskVolumeSource"]:
        '''VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.PersistentVolumeSpec#vsphereVolume
        '''
        result = self._values.get("vsphere_volume")
        return typing.cast(typing.Optional["VsphereVirtualDiskVolumeSource"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PersistentVolumeSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PhotonPersistentDiskVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"pd_id": "pdId", "fs_type": "fsType"},
)
class PhotonPersistentDiskVolumeSource:
    def __init__(
        self,
        *,
        pd_id: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Photon Controller persistent disk resource.

        :param pd_id: ID that identifies Photon Controller persistent disk.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.PhotonPersistentDiskVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                pd_id: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pd_id", value=pd_id, expected_type=type_hints["pd_id"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
        self._values: typing.Dict[str, typing.Any] = {
            "pd_id": pd_id,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type

    @builtins.property
    def pd_id(self) -> builtins.str:
        '''ID that identifies Photon Controller persistent disk.

        :schema: io.k8s.api.core.v1.PhotonPersistentDiskVolumeSource#pdID
        '''
        result = self._values.get("pd_id")
        assert result is not None, "Required property 'pd_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.PhotonPersistentDiskVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PhotonPersistentDiskVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodAffinity",
    jsii_struct_bases=[],
    name_mapping={
        "preferred_during_scheduling_ignored_during_execution": "preferredDuringSchedulingIgnoredDuringExecution",
        "required_during_scheduling_ignored_during_execution": "requiredDuringSchedulingIgnoredDuringExecution",
    },
)
class PodAffinity:
    def __init__(
        self,
        *,
        preferred_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union["WeightedPodAffinityTerm", typing.Dict[str, typing.Any]]]] = None,
        required_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union["PodAffinityTerm", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Pod affinity is a group of inter pod affinity scheduling rules.

        :param preferred_during_scheduling_ignored_during_execution: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.
        :param required_during_scheduling_ignored_during_execution: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

        :schema: io.k8s.api.core.v1.PodAffinity
        '''
        if __debug__:
            def stub(
                *,
                preferred_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union[WeightedPodAffinityTerm, typing.Dict[str, typing.Any]]]] = None,
                required_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union[PodAffinityTerm, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument preferred_during_scheduling_ignored_during_execution", value=preferred_during_scheduling_ignored_during_execution, expected_type=type_hints["preferred_during_scheduling_ignored_during_execution"])
            check_type(argname="argument required_during_scheduling_ignored_during_execution", value=required_during_scheduling_ignored_during_execution, expected_type=type_hints["required_during_scheduling_ignored_during_execution"])
        self._values: typing.Dict[str, typing.Any] = {}
        if preferred_during_scheduling_ignored_during_execution is not None:
            self._values["preferred_during_scheduling_ignored_during_execution"] = preferred_during_scheduling_ignored_during_execution
        if required_during_scheduling_ignored_during_execution is not None:
            self._values["required_during_scheduling_ignored_during_execution"] = required_during_scheduling_ignored_during_execution

    @builtins.property
    def preferred_during_scheduling_ignored_during_execution(
        self,
    ) -> typing.Optional[typing.List["WeightedPodAffinityTerm"]]:
        '''The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions.

        The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

        :schema: io.k8s.api.core.v1.PodAffinity#preferredDuringSchedulingIgnoredDuringExecution
        '''
        result = self._values.get("preferred_during_scheduling_ignored_during_execution")
        return typing.cast(typing.Optional[typing.List["WeightedPodAffinityTerm"]], result)

    @builtins.property
    def required_during_scheduling_ignored_during_execution(
        self,
    ) -> typing.Optional[typing.List["PodAffinityTerm"]]:
        '''If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node.

        If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

        :schema: io.k8s.api.core.v1.PodAffinity#requiredDuringSchedulingIgnoredDuringExecution
        '''
        result = self._values.get("required_during_scheduling_ignored_during_execution")
        return typing.cast(typing.Optional[typing.List["PodAffinityTerm"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodAffinity(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodAffinityTerm",
    jsii_struct_bases=[],
    name_mapping={
        "topology_key": "topologyKey",
        "label_selector": "labelSelector",
        "namespaces": "namespaces",
        "namespace_selector": "namespaceSelector",
    },
)
class PodAffinityTerm:
    def __init__(
        self,
        *,
        topology_key: builtins.str,
        label_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        namespaces: typing.Optional[typing.Sequence[builtins.str]] = None,
        namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key  matches that of any node on which a pod of the set of pods is running.

        :param topology_key: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.
        :param label_selector: A label query over a set of resources, in this case pods.
        :param namespaces: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
        :param namespace_selector: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled.

        :schema: io.k8s.api.core.v1.PodAffinityTerm
        '''
        if isinstance(label_selector, dict):
            label_selector = LabelSelector(**label_selector)
        if isinstance(namespace_selector, dict):
            namespace_selector = LabelSelector(**namespace_selector)
        if __debug__:
            def stub(
                *,
                topology_key: builtins.str,
                label_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                namespaces: typing.Optional[typing.Sequence[builtins.str]] = None,
                namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument topology_key", value=topology_key, expected_type=type_hints["topology_key"])
            check_type(argname="argument label_selector", value=label_selector, expected_type=type_hints["label_selector"])
            check_type(argname="argument namespaces", value=namespaces, expected_type=type_hints["namespaces"])
            check_type(argname="argument namespace_selector", value=namespace_selector, expected_type=type_hints["namespace_selector"])
        self._values: typing.Dict[str, typing.Any] = {
            "topology_key": topology_key,
        }
        if label_selector is not None:
            self._values["label_selector"] = label_selector
        if namespaces is not None:
            self._values["namespaces"] = namespaces
        if namespace_selector is not None:
            self._values["namespace_selector"] = namespace_selector

    @builtins.property
    def topology_key(self) -> builtins.str:
        '''This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running.

        Empty topologyKey is not allowed.

        :schema: io.k8s.api.core.v1.PodAffinityTerm#topologyKey
        '''
        result = self._values.get("topology_key")
        assert result is not None, "Required property 'topology_key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def label_selector(self) -> typing.Optional[LabelSelector]:
        '''A label query over a set of resources, in this case pods.

        :schema: io.k8s.api.core.v1.PodAffinityTerm#labelSelector
        '''
        result = self._values.get("label_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def namespaces(self) -> typing.Optional[typing.List[builtins.str]]:
        '''namespaces specifies a static list of namespace names that the term applies to.

        The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"

        :schema: io.k8s.api.core.v1.PodAffinityTerm#namespaces
        '''
        result = self._values.get("namespaces")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def namespace_selector(self) -> typing.Optional[LabelSelector]:
        '''A label query over the set of namespaces that the term applies to.

        The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled.

        :schema: io.k8s.api.core.v1.PodAffinityTerm#namespaceSelector
        '''
        result = self._values.get("namespace_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodAffinityTerm(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodAntiAffinity",
    jsii_struct_bases=[],
    name_mapping={
        "preferred_during_scheduling_ignored_during_execution": "preferredDuringSchedulingIgnoredDuringExecution",
        "required_during_scheduling_ignored_during_execution": "requiredDuringSchedulingIgnoredDuringExecution",
    },
)
class PodAntiAffinity:
    def __init__(
        self,
        *,
        preferred_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union["WeightedPodAffinityTerm", typing.Dict[str, typing.Any]]]] = None,
        required_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union[PodAffinityTerm, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Pod anti affinity is a group of inter pod anti affinity scheduling rules.

        :param preferred_during_scheduling_ignored_during_execution: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.
        :param required_during_scheduling_ignored_during_execution: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

        :schema: io.k8s.api.core.v1.PodAntiAffinity
        '''
        if __debug__:
            def stub(
                *,
                preferred_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union[WeightedPodAffinityTerm, typing.Dict[str, typing.Any]]]] = None,
                required_during_scheduling_ignored_during_execution: typing.Optional[typing.Sequence[typing.Union[PodAffinityTerm, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument preferred_during_scheduling_ignored_during_execution", value=preferred_during_scheduling_ignored_during_execution, expected_type=type_hints["preferred_during_scheduling_ignored_during_execution"])
            check_type(argname="argument required_during_scheduling_ignored_during_execution", value=required_during_scheduling_ignored_during_execution, expected_type=type_hints["required_during_scheduling_ignored_during_execution"])
        self._values: typing.Dict[str, typing.Any] = {}
        if preferred_during_scheduling_ignored_during_execution is not None:
            self._values["preferred_during_scheduling_ignored_during_execution"] = preferred_during_scheduling_ignored_during_execution
        if required_during_scheduling_ignored_during_execution is not None:
            self._values["required_during_scheduling_ignored_during_execution"] = required_during_scheduling_ignored_during_execution

    @builtins.property
    def preferred_during_scheduling_ignored_during_execution(
        self,
    ) -> typing.Optional[typing.List["WeightedPodAffinityTerm"]]:
        '''The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions.

        The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

        :schema: io.k8s.api.core.v1.PodAntiAffinity#preferredDuringSchedulingIgnoredDuringExecution
        '''
        result = self._values.get("preferred_during_scheduling_ignored_during_execution")
        return typing.cast(typing.Optional[typing.List["WeightedPodAffinityTerm"]], result)

    @builtins.property
    def required_during_scheduling_ignored_during_execution(
        self,
    ) -> typing.Optional[typing.List[PodAffinityTerm]]:
        '''If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node.

        If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

        :schema: io.k8s.api.core.v1.PodAntiAffinity#requiredDuringSchedulingIgnoredDuringExecution
        '''
        result = self._values.get("required_during_scheduling_ignored_during_execution")
        return typing.cast(typing.Optional[typing.List[PodAffinityTerm]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodAntiAffinity(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodDisruptionBudgetSpec",
    jsii_struct_bases=[],
    name_mapping={
        "max_unavailable": "maxUnavailable",
        "min_available": "minAvailable",
        "selector": "selector",
    },
)
class PodDisruptionBudgetSpec:
    def __init__(
        self,
        *,
        max_unavailable: typing.Optional[IntOrString] = None,
        min_available: typing.Optional[IntOrString] = None,
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.

        :param max_unavailable: An eviction is allowed if at most "maxUnavailable" pods selected by "selector" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with "minAvailable".
        :param min_available: An eviction is allowed if at least "minAvailable" pods selected by "selector" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying "100%".
        :param selector: Label query over pods whose evictions are managed by the disruption budget. A null selector will match no pods, while an empty ({}) selector will select all pods within the namespace.

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetSpec
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                max_unavailable: typing.Optional[IntOrString] = None,
                min_available: typing.Optional[IntOrString] = None,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_unavailable", value=max_unavailable, expected_type=type_hints["max_unavailable"])
            check_type(argname="argument min_available", value=min_available, expected_type=type_hints["min_available"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
        self._values: typing.Dict[str, typing.Any] = {}
        if max_unavailable is not None:
            self._values["max_unavailable"] = max_unavailable
        if min_available is not None:
            self._values["min_available"] = min_available
        if selector is not None:
            self._values["selector"] = selector

    @builtins.property
    def max_unavailable(self) -> typing.Optional[IntOrString]:
        '''An eviction is allowed if at most "maxUnavailable" pods selected by "selector" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with "minAvailable".

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetSpec#maxUnavailable
        '''
        result = self._values.get("max_unavailable")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def min_available(self) -> typing.Optional[IntOrString]:
        '''An eviction is allowed if at least "minAvailable" pods selected by "selector" will still be available after the eviction, i.e. even in the absence of the evicted pod.  So for example you can prevent all voluntary evictions by specifying "100%".

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetSpec#minAvailable
        '''
        result = self._values.get("min_available")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''Label query over pods whose evictions are managed by the disruption budget.

        A null selector will match no pods, while an empty ({}) selector will select all pods within the namespace.

        :schema: io.k8s.api.policy.v1.PodDisruptionBudgetSpec#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodDisruptionBudgetSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodDisruptionBudgetSpecV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "max_unavailable": "maxUnavailable",
        "min_available": "minAvailable",
        "selector": "selector",
    },
)
class PodDisruptionBudgetSpecV1Beta1:
    def __init__(
        self,
        *,
        max_unavailable: typing.Optional[IntOrString] = None,
        min_available: typing.Optional[IntOrString] = None,
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.

        :param max_unavailable: An eviction is allowed if at most "maxUnavailable" pods selected by "selector" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with "minAvailable".
        :param min_available: An eviction is allowed if at least "minAvailable" pods selected by "selector" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying "100%".
        :param selector: Label query over pods whose evictions are managed by the disruption budget. A null selector selects no pods. An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. In policy/v1, an empty selector will select all pods in the namespace.

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetSpec
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                max_unavailable: typing.Optional[IntOrString] = None,
                min_available: typing.Optional[IntOrString] = None,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_unavailable", value=max_unavailable, expected_type=type_hints["max_unavailable"])
            check_type(argname="argument min_available", value=min_available, expected_type=type_hints["min_available"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
        self._values: typing.Dict[str, typing.Any] = {}
        if max_unavailable is not None:
            self._values["max_unavailable"] = max_unavailable
        if min_available is not None:
            self._values["min_available"] = min_available
        if selector is not None:
            self._values["selector"] = selector

    @builtins.property
    def max_unavailable(self) -> typing.Optional[IntOrString]:
        '''An eviction is allowed if at most "maxUnavailable" pods selected by "selector" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with "minAvailable".

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetSpec#maxUnavailable
        '''
        result = self._values.get("max_unavailable")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def min_available(self) -> typing.Optional[IntOrString]:
        '''An eviction is allowed if at least "minAvailable" pods selected by "selector" will still be available after the eviction, i.e. even in the absence of the evicted pod.  So for example you can prevent all voluntary evictions by specifying "100%".

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetSpec#minAvailable
        '''
        result = self._values.get("min_available")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''Label query over pods whose evictions are managed by the disruption budget.

        A null selector selects no pods. An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. In policy/v1, an empty selector will select all pods in the namespace.

        :schema: io.k8s.api.policy.v1beta1.PodDisruptionBudgetSpec#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodDisruptionBudgetSpecV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodDnsConfig",
    jsii_struct_bases=[],
    name_mapping={
        "nameservers": "nameservers",
        "options": "options",
        "searches": "searches",
    },
)
class PodDnsConfig:
    def __init__(
        self,
        *,
        nameservers: typing.Optional[typing.Sequence[builtins.str]] = None,
        options: typing.Optional[typing.Sequence[typing.Union["PodDnsConfigOption", typing.Dict[str, typing.Any]]]] = None,
        searches: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''PodDNSConfig defines the DNS parameters of a pod in addition to those generated from DNSPolicy.

        :param nameservers: A list of DNS name server IP addresses. This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed.
        :param options: A list of DNS resolver options. This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy.
        :param searches: A list of DNS search domains for host-name lookup. This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed.

        :schema: io.k8s.api.core.v1.PodDNSConfig
        '''
        if __debug__:
            def stub(
                *,
                nameservers: typing.Optional[typing.Sequence[builtins.str]] = None,
                options: typing.Optional[typing.Sequence[typing.Union[PodDnsConfigOption, typing.Dict[str, typing.Any]]]] = None,
                searches: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument nameservers", value=nameservers, expected_type=type_hints["nameservers"])
            check_type(argname="argument options", value=options, expected_type=type_hints["options"])
            check_type(argname="argument searches", value=searches, expected_type=type_hints["searches"])
        self._values: typing.Dict[str, typing.Any] = {}
        if nameservers is not None:
            self._values["nameservers"] = nameservers
        if options is not None:
            self._values["options"] = options
        if searches is not None:
            self._values["searches"] = searches

    @builtins.property
    def nameservers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''A list of DNS name server IP addresses.

        This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed.

        :schema: io.k8s.api.core.v1.PodDNSConfig#nameservers
        '''
        result = self._values.get("nameservers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def options(self) -> typing.Optional[typing.List["PodDnsConfigOption"]]:
        '''A list of DNS resolver options.

        This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy.

        :schema: io.k8s.api.core.v1.PodDNSConfig#options
        '''
        result = self._values.get("options")
        return typing.cast(typing.Optional[typing.List["PodDnsConfigOption"]], result)

    @builtins.property
    def searches(self) -> typing.Optional[typing.List[builtins.str]]:
        '''A list of DNS search domains for host-name lookup.

        This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed.

        :schema: io.k8s.api.core.v1.PodDNSConfig#searches
        '''
        result = self._values.get("searches")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodDnsConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodDnsConfigOption",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "value": "value"},
)
class PodDnsConfigOption:
    def __init__(
        self,
        *,
        name: typing.Optional[builtins.str] = None,
        value: typing.Optional[builtins.str] = None,
    ) -> None:
        '''PodDNSConfigOption defines DNS resolver options of a pod.

        :param name: Required.
        :param value: 

        :schema: io.k8s.api.core.v1.PodDNSConfigOption
        '''
        if __debug__:
            def stub(
                *,
                name: typing.Optional[builtins.str] = None,
                value: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {}
        if name is not None:
            self._values["name"] = name
        if value is not None:
            self._values["value"] = value

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Required.

        :schema: io.k8s.api.core.v1.PodDNSConfigOption#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def value(self) -> typing.Optional[builtins.str]:
        '''
        :schema: io.k8s.api.core.v1.PodDNSConfigOption#value
        '''
        result = self._values.get("value")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodDnsConfigOption(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodOs",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class PodOs:
    def __init__(self, *, name: builtins.str) -> None:
        '''PodOS defines the OS parameters of a pod.

        :param name: Name is the name of the operating system. The currently supported values are linux and windows. Additional value may be defined in future and can be one of: https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration Clients should expect to handle additional values and treat unrecognized values in this field as os: null

        :schema: io.k8s.api.core.v1.PodOS
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the name of the operating system.

        The currently supported values are linux and windows. Additional value may be defined in future and can be one of: https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration Clients should expect to handle additional values and treat unrecognized values in this field as os: null

        :schema: io.k8s.api.core.v1.PodOS#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodOs(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodReadinessGate",
    jsii_struct_bases=[],
    name_mapping={"condition_type": "conditionType"},
)
class PodReadinessGate:
    def __init__(
        self,
        *,
        condition_type: IoK8SApiCoreV1PodReadinessGateConditionType,
    ) -> None:
        '''PodReadinessGate contains the reference to a pod condition.

        :param condition_type: ConditionType refers to a condition in the pod's condition list with matching type. Possible enum values: - ``"ContainersReady"`` indicates whether all containers in the pod are ready. - ``"Initialized"`` means that all init containers in the pod have started successfully. - ``"PodScheduled"`` represents status of the scheduling process for this pod. - ``"Ready"`` means the pod is able to service requests and should be added to the load balancing pools of all matching services.

        :schema: io.k8s.api.core.v1.PodReadinessGate
        '''
        if __debug__:
            def stub(
                *,
                condition_type: IoK8SApiCoreV1PodReadinessGateConditionType,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument condition_type", value=condition_type, expected_type=type_hints["condition_type"])
        self._values: typing.Dict[str, typing.Any] = {
            "condition_type": condition_type,
        }

    @builtins.property
    def condition_type(self) -> IoK8SApiCoreV1PodReadinessGateConditionType:
        '''ConditionType refers to a condition in the pod's condition list with matching type.

        Possible enum values:

        - ``"ContainersReady"`` indicates whether all containers in the pod are ready.
        - ``"Initialized"`` means that all init containers in the pod have started successfully.
        - ``"PodScheduled"`` represents status of the scheduling process for this pod.
        - ``"Ready"`` means the pod is able to service requests and should be added to the load balancing pools of all matching services.

        :schema: io.k8s.api.core.v1.PodReadinessGate#conditionType
        '''
        result = self._values.get("condition_type")
        assert result is not None, "Required property 'condition_type' is missing"
        return typing.cast(IoK8SApiCoreV1PodReadinessGateConditionType, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodReadinessGate(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodSecurityContext",
    jsii_struct_bases=[],
    name_mapping={
        "fs_group": "fsGroup",
        "fs_group_change_policy": "fsGroupChangePolicy",
        "run_as_group": "runAsGroup",
        "run_as_non_root": "runAsNonRoot",
        "run_as_user": "runAsUser",
        "seccomp_profile": "seccompProfile",
        "se_linux_options": "seLinuxOptions",
        "supplemental_groups": "supplementalGroups",
        "sysctls": "sysctls",
        "windows_options": "windowsOptions",
    },
)
class PodSecurityContext:
    def __init__(
        self,
        *,
        fs_group: typing.Optional[jsii.Number] = None,
        fs_group_change_policy: typing.Optional[builtins.str] = None,
        run_as_group: typing.Optional[jsii.Number] = None,
        run_as_non_root: typing.Optional[builtins.bool] = None,
        run_as_user: typing.Optional[jsii.Number] = None,
        seccomp_profile: typing.Optional[typing.Union["SeccompProfile", typing.Dict[str, typing.Any]]] = None,
        se_linux_options: typing.Optional[typing.Union["SeLinuxOptions", typing.Dict[str, typing.Any]]] = None,
        supplemental_groups: typing.Optional[typing.Sequence[jsii.Number]] = None,
        sysctls: typing.Optional[typing.Sequence[typing.Union["Sysctl", typing.Dict[str, typing.Any]]]] = None,
        windows_options: typing.Optional[typing.Union["WindowsSecurityContextOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodSecurityContext holds pod-level security attributes and common container settings.

        Some fields are also present in container.securityContext.  Field values of container.securityContext take precedence over field values of PodSecurityContext.

        :param fs_group: A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows.
        :param fs_group_change_policy: fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.
        :param run_as_group: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.
        :param run_as_non_root: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.
        :param run_as_user: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. Default: user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.
        :param seccomp_profile: The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows.
        :param se_linux_options: The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.
        :param supplemental_groups: A list of groups applied to the first process run in each container, in addition to the container's primary GID. If unspecified, no groups will be added to any container. Note that this field cannot be set when spec.os.name is windows.
        :param sysctls: Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows.
        :param windows_options: The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux.

        :schema: io.k8s.api.core.v1.PodSecurityContext
        '''
        if isinstance(seccomp_profile, dict):
            seccomp_profile = SeccompProfile(**seccomp_profile)
        if isinstance(se_linux_options, dict):
            se_linux_options = SeLinuxOptions(**se_linux_options)
        if isinstance(windows_options, dict):
            windows_options = WindowsSecurityContextOptions(**windows_options)
        if __debug__:
            def stub(
                *,
                fs_group: typing.Optional[jsii.Number] = None,
                fs_group_change_policy: typing.Optional[builtins.str] = None,
                run_as_group: typing.Optional[jsii.Number] = None,
                run_as_non_root: typing.Optional[builtins.bool] = None,
                run_as_user: typing.Optional[jsii.Number] = None,
                seccomp_profile: typing.Optional[typing.Union[SeccompProfile, typing.Dict[str, typing.Any]]] = None,
                se_linux_options: typing.Optional[typing.Union[SeLinuxOptions, typing.Dict[str, typing.Any]]] = None,
                supplemental_groups: typing.Optional[typing.Sequence[jsii.Number]] = None,
                sysctls: typing.Optional[typing.Sequence[typing.Union[Sysctl, typing.Dict[str, typing.Any]]]] = None,
                windows_options: typing.Optional[typing.Union[WindowsSecurityContextOptions, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument fs_group", value=fs_group, expected_type=type_hints["fs_group"])
            check_type(argname="argument fs_group_change_policy", value=fs_group_change_policy, expected_type=type_hints["fs_group_change_policy"])
            check_type(argname="argument run_as_group", value=run_as_group, expected_type=type_hints["run_as_group"])
            check_type(argname="argument run_as_non_root", value=run_as_non_root, expected_type=type_hints["run_as_non_root"])
            check_type(argname="argument run_as_user", value=run_as_user, expected_type=type_hints["run_as_user"])
            check_type(argname="argument seccomp_profile", value=seccomp_profile, expected_type=type_hints["seccomp_profile"])
            check_type(argname="argument se_linux_options", value=se_linux_options, expected_type=type_hints["se_linux_options"])
            check_type(argname="argument supplemental_groups", value=supplemental_groups, expected_type=type_hints["supplemental_groups"])
            check_type(argname="argument sysctls", value=sysctls, expected_type=type_hints["sysctls"])
            check_type(argname="argument windows_options", value=windows_options, expected_type=type_hints["windows_options"])
        self._values: typing.Dict[str, typing.Any] = {}
        if fs_group is not None:
            self._values["fs_group"] = fs_group
        if fs_group_change_policy is not None:
            self._values["fs_group_change_policy"] = fs_group_change_policy
        if run_as_group is not None:
            self._values["run_as_group"] = run_as_group
        if run_as_non_root is not None:
            self._values["run_as_non_root"] = run_as_non_root
        if run_as_user is not None:
            self._values["run_as_user"] = run_as_user
        if seccomp_profile is not None:
            self._values["seccomp_profile"] = seccomp_profile
        if se_linux_options is not None:
            self._values["se_linux_options"] = se_linux_options
        if supplemental_groups is not None:
            self._values["supplemental_groups"] = supplemental_groups
        if sysctls is not None:
            self._values["sysctls"] = sysctls
        if windows_options is not None:
            self._values["windows_options"] = windows_options

    @builtins.property
    def fs_group(self) -> typing.Optional[jsii.Number]:
        '''A special supplemental group that applies to all containers in a pod.

        Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod:

        1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw----

        If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#fsGroup
        '''
        result = self._values.get("fs_group")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def fs_group_change_policy(self) -> typing.Optional[builtins.str]:
        '''fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod.

        This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#fsGroupChangePolicy
        '''
        result = self._values.get("fs_group_change_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def run_as_group(self) -> typing.Optional[jsii.Number]:
        '''The GID to run the entrypoint of the container process.

        Uses runtime default if unset. May also be set in SecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#runAsGroup
        '''
        result = self._values.get("run_as_group")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def run_as_non_root(self) -> typing.Optional[builtins.bool]:
        '''Indicates that the container must run as a non-root user.

        If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.

        :schema: io.k8s.api.core.v1.PodSecurityContext#runAsNonRoot
        '''
        result = self._values.get("run_as_non_root")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def run_as_user(self) -> typing.Optional[jsii.Number]:
        '''The UID to run the entrypoint of the container process.

        Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.

        :default: user specified in image metadata if unspecified. May also be set in SecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#runAsUser
        '''
        result = self._values.get("run_as_user")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def seccomp_profile(self) -> typing.Optional["SeccompProfile"]:
        '''The seccomp options to use by the containers in this pod.

        Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#seccompProfile
        '''
        result = self._values.get("seccomp_profile")
        return typing.cast(typing.Optional["SeccompProfile"], result)

    @builtins.property
    def se_linux_options(self) -> typing.Optional["SeLinuxOptions"]:
        '''The SELinux context to be applied to all containers.

        If unspecified, the container runtime will allocate a random SELinux context for each container.  May also be set in SecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#seLinuxOptions
        '''
        result = self._values.get("se_linux_options")
        return typing.cast(typing.Optional["SeLinuxOptions"], result)

    @builtins.property
    def supplemental_groups(self) -> typing.Optional[typing.List[jsii.Number]]:
        '''A list of groups applied to the first process run in each container, in addition to the container's primary GID.

        If unspecified, no groups will be added to any container. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#supplementalGroups
        '''
        result = self._values.get("supplemental_groups")
        return typing.cast(typing.Optional[typing.List[jsii.Number]], result)

    @builtins.property
    def sysctls(self) -> typing.Optional[typing.List["Sysctl"]]:
        '''Sysctls hold a list of namespaced sysctls used for the pod.

        Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.PodSecurityContext#sysctls
        '''
        result = self._values.get("sysctls")
        return typing.cast(typing.Optional[typing.List["Sysctl"]], result)

    @builtins.property
    def windows_options(self) -> typing.Optional["WindowsSecurityContextOptions"]:
        '''The Windows specific settings applied to all containers.

        If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux.

        :schema: io.k8s.api.core.v1.PodSecurityContext#windowsOptions
        '''
        result = self._values.get("windows_options")
        return typing.cast(typing.Optional["WindowsSecurityContextOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodSecurityContext(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodSecurityPolicySpecV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "fs_group": "fsGroup",
        "run_as_user": "runAsUser",
        "se_linux": "seLinux",
        "supplemental_groups": "supplementalGroups",
        "allowed_capabilities": "allowedCapabilities",
        "allowed_csi_drivers": "allowedCsiDrivers",
        "allowed_flex_volumes": "allowedFlexVolumes",
        "allowed_host_paths": "allowedHostPaths",
        "allowed_proc_mount_types": "allowedProcMountTypes",
        "allowed_unsafe_sysctls": "allowedUnsafeSysctls",
        "allow_privilege_escalation": "allowPrivilegeEscalation",
        "default_add_capabilities": "defaultAddCapabilities",
        "default_allow_privilege_escalation": "defaultAllowPrivilegeEscalation",
        "forbidden_sysctls": "forbiddenSysctls",
        "host_ipc": "hostIpc",
        "host_network": "hostNetwork",
        "host_pid": "hostPid",
        "host_ports": "hostPorts",
        "privileged": "privileged",
        "read_only_root_filesystem": "readOnlyRootFilesystem",
        "required_drop_capabilities": "requiredDropCapabilities",
        "run_as_group": "runAsGroup",
        "runtime_class": "runtimeClass",
        "volumes": "volumes",
    },
)
class PodSecurityPolicySpecV1Beta1:
    def __init__(
        self,
        *,
        fs_group: typing.Union[FsGroupStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]],
        run_as_user: typing.Union["RunAsUserStrategyOptionsV1Beta1", typing.Dict[str, typing.Any]],
        se_linux: typing.Union["SeLinuxStrategyOptionsV1Beta1", typing.Dict[str, typing.Any]],
        supplemental_groups: typing.Union["SupplementalGroupsStrategyOptionsV1Beta1", typing.Dict[str, typing.Any]],
        allowed_capabilities: typing.Optional[typing.Sequence[builtins.str]] = None,
        allowed_csi_drivers: typing.Optional[typing.Sequence[typing.Union[AllowedCsiDriverV1Beta1, typing.Dict[str, typing.Any]]]] = None,
        allowed_flex_volumes: typing.Optional[typing.Sequence[typing.Union[AllowedFlexVolumeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
        allowed_host_paths: typing.Optional[typing.Sequence[typing.Union[AllowedHostPathV1Beta1, typing.Dict[str, typing.Any]]]] = None,
        allowed_proc_mount_types: typing.Optional[typing.Sequence[builtins.str]] = None,
        allowed_unsafe_sysctls: typing.Optional[typing.Sequence[builtins.str]] = None,
        allow_privilege_escalation: typing.Optional[builtins.bool] = None,
        default_add_capabilities: typing.Optional[typing.Sequence[builtins.str]] = None,
        default_allow_privilege_escalation: typing.Optional[builtins.bool] = None,
        forbidden_sysctls: typing.Optional[typing.Sequence[builtins.str]] = None,
        host_ipc: typing.Optional[builtins.bool] = None,
        host_network: typing.Optional[builtins.bool] = None,
        host_pid: typing.Optional[builtins.bool] = None,
        host_ports: typing.Optional[typing.Sequence[typing.Union[HostPortRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
        privileged: typing.Optional[builtins.bool] = None,
        read_only_root_filesystem: typing.Optional[builtins.bool] = None,
        required_drop_capabilities: typing.Optional[typing.Sequence[builtins.str]] = None,
        run_as_group: typing.Optional[typing.Union["RunAsGroupStrategyOptionsV1Beta1", typing.Dict[str, typing.Any]]] = None,
        runtime_class: typing.Optional[typing.Union["RuntimeClassStrategyOptionsV1Beta1", typing.Dict[str, typing.Any]]] = None,
        volumes: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''PodSecurityPolicySpec defines the policy enforced.

        :param fs_group: fsGroup is the strategy that will dictate what fs group is used by the SecurityContext.
        :param run_as_user: runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.
        :param se_linux: seLinux is the strategy that will dictate the allowable labels that may be set.
        :param supplemental_groups: supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext.
        :param allowed_capabilities: allowedCapabilities is a list of capabilities that can be requested to add to the container. Capabilities in this field may be added at the pod author's discretion. You must not list a capability in both allowedCapabilities and requiredDropCapabilities.
        :param allowed_csi_drivers: AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes. This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.
        :param allowed_flex_volumes: allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the "volumes" field.
        :param allowed_host_paths: allowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used.
        :param allowed_proc_mount_types: AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.
        :param allowed_unsafe_sysctls: allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in "*" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all allowed unsafe sysctls explicitly to avoid rejection. Examples: e.g. "foo/*" allows "foo/bar", "foo/baz", etc. e.g. "foo.*" allows "foo.bar", "foo.baz", etc.
        :param allow_privilege_escalation: allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.
        :param default_add_capabilities: defaultAddCapabilities is the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability. You may not list a capability in both defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly allowed, and need not be included in the allowedCapabilities list.
        :param default_allow_privilege_escalation: defaultAllowPrivilegeEscalation controls the default setting for whether a process can gain more privileges than its parent process.
        :param forbidden_sysctls: forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in "*" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. Examples: e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. e.g. "foo.*" forbids "foo.bar", "foo.baz", etc.
        :param host_ipc: hostIPC determines if the policy allows the use of HostIPC in the pod spec.
        :param host_network: hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.
        :param host_pid: hostPID determines if the policy allows the use of HostPID in the pod spec.
        :param host_ports: hostPorts determines which host port ranges are allowed to be exposed.
        :param privileged: privileged determines if a pod can request to be run as privileged.
        :param read_only_root_filesystem: readOnlyRootFilesystem when set to true will force containers to run with a read only root file system. If the container specifically requests to run with a non-read only root file system the PSP should deny the pod. If set to false the container may run with a read only root file system if it wishes but it will not be forced to.
        :param required_drop_capabilities: requiredDropCapabilities are the capabilities that will be dropped from the container. These are required to be dropped and cannot be added.
        :param run_as_group: RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. If this field is omitted, the pod's RunAsGroup can take any value. This field requires the RunAsGroup feature gate to be enabled.
        :param runtime_class: runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. If this field is omitted, the pod's runtimeClassName field is unrestricted. Enforcement of this field depends on the RuntimeClass feature gate being enabled.
        :param volumes: volumes is an allowlist of volume plugins. Empty indicates that no volumes may be used. To allow all volumes you may use '*'.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec
        '''
        if isinstance(fs_group, dict):
            fs_group = FsGroupStrategyOptionsV1Beta1(**fs_group)
        if isinstance(run_as_user, dict):
            run_as_user = RunAsUserStrategyOptionsV1Beta1(**run_as_user)
        if isinstance(se_linux, dict):
            se_linux = SeLinuxStrategyOptionsV1Beta1(**se_linux)
        if isinstance(supplemental_groups, dict):
            supplemental_groups = SupplementalGroupsStrategyOptionsV1Beta1(**supplemental_groups)
        if isinstance(run_as_group, dict):
            run_as_group = RunAsGroupStrategyOptionsV1Beta1(**run_as_group)
        if isinstance(runtime_class, dict):
            runtime_class = RuntimeClassStrategyOptionsV1Beta1(**runtime_class)
        if __debug__:
            def stub(
                *,
                fs_group: typing.Union[FsGroupStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]],
                run_as_user: typing.Union[RunAsUserStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]],
                se_linux: typing.Union[SeLinuxStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]],
                supplemental_groups: typing.Union[SupplementalGroupsStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]],
                allowed_capabilities: typing.Optional[typing.Sequence[builtins.str]] = None,
                allowed_csi_drivers: typing.Optional[typing.Sequence[typing.Union[AllowedCsiDriverV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                allowed_flex_volumes: typing.Optional[typing.Sequence[typing.Union[AllowedFlexVolumeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                allowed_host_paths: typing.Optional[typing.Sequence[typing.Union[AllowedHostPathV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                allowed_proc_mount_types: typing.Optional[typing.Sequence[builtins.str]] = None,
                allowed_unsafe_sysctls: typing.Optional[typing.Sequence[builtins.str]] = None,
                allow_privilege_escalation: typing.Optional[builtins.bool] = None,
                default_add_capabilities: typing.Optional[typing.Sequence[builtins.str]] = None,
                default_allow_privilege_escalation: typing.Optional[builtins.bool] = None,
                forbidden_sysctls: typing.Optional[typing.Sequence[builtins.str]] = None,
                host_ipc: typing.Optional[builtins.bool] = None,
                host_network: typing.Optional[builtins.bool] = None,
                host_pid: typing.Optional[builtins.bool] = None,
                host_ports: typing.Optional[typing.Sequence[typing.Union[HostPortRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                privileged: typing.Optional[builtins.bool] = None,
                read_only_root_filesystem: typing.Optional[builtins.bool] = None,
                required_drop_capabilities: typing.Optional[typing.Sequence[builtins.str]] = None,
                run_as_group: typing.Optional[typing.Union[RunAsGroupStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]]] = None,
                runtime_class: typing.Optional[typing.Union[RuntimeClassStrategyOptionsV1Beta1, typing.Dict[str, typing.Any]]] = None,
                volumes: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument fs_group", value=fs_group, expected_type=type_hints["fs_group"])
            check_type(argname="argument run_as_user", value=run_as_user, expected_type=type_hints["run_as_user"])
            check_type(argname="argument se_linux", value=se_linux, expected_type=type_hints["se_linux"])
            check_type(argname="argument supplemental_groups", value=supplemental_groups, expected_type=type_hints["supplemental_groups"])
            check_type(argname="argument allowed_capabilities", value=allowed_capabilities, expected_type=type_hints["allowed_capabilities"])
            check_type(argname="argument allowed_csi_drivers", value=allowed_csi_drivers, expected_type=type_hints["allowed_csi_drivers"])
            check_type(argname="argument allowed_flex_volumes", value=allowed_flex_volumes, expected_type=type_hints["allowed_flex_volumes"])
            check_type(argname="argument allowed_host_paths", value=allowed_host_paths, expected_type=type_hints["allowed_host_paths"])
            check_type(argname="argument allowed_proc_mount_types", value=allowed_proc_mount_types, expected_type=type_hints["allowed_proc_mount_types"])
            check_type(argname="argument allowed_unsafe_sysctls", value=allowed_unsafe_sysctls, expected_type=type_hints["allowed_unsafe_sysctls"])
            check_type(argname="argument allow_privilege_escalation", value=allow_privilege_escalation, expected_type=type_hints["allow_privilege_escalation"])
            check_type(argname="argument default_add_capabilities", value=default_add_capabilities, expected_type=type_hints["default_add_capabilities"])
            check_type(argname="argument default_allow_privilege_escalation", value=default_allow_privilege_escalation, expected_type=type_hints["default_allow_privilege_escalation"])
            check_type(argname="argument forbidden_sysctls", value=forbidden_sysctls, expected_type=type_hints["forbidden_sysctls"])
            check_type(argname="argument host_ipc", value=host_ipc, expected_type=type_hints["host_ipc"])
            check_type(argname="argument host_network", value=host_network, expected_type=type_hints["host_network"])
            check_type(argname="argument host_pid", value=host_pid, expected_type=type_hints["host_pid"])
            check_type(argname="argument host_ports", value=host_ports, expected_type=type_hints["host_ports"])
            check_type(argname="argument privileged", value=privileged, expected_type=type_hints["privileged"])
            check_type(argname="argument read_only_root_filesystem", value=read_only_root_filesystem, expected_type=type_hints["read_only_root_filesystem"])
            check_type(argname="argument required_drop_capabilities", value=required_drop_capabilities, expected_type=type_hints["required_drop_capabilities"])
            check_type(argname="argument run_as_group", value=run_as_group, expected_type=type_hints["run_as_group"])
            check_type(argname="argument runtime_class", value=runtime_class, expected_type=type_hints["runtime_class"])
            check_type(argname="argument volumes", value=volumes, expected_type=type_hints["volumes"])
        self._values: typing.Dict[str, typing.Any] = {
            "fs_group": fs_group,
            "run_as_user": run_as_user,
            "se_linux": se_linux,
            "supplemental_groups": supplemental_groups,
        }
        if allowed_capabilities is not None:
            self._values["allowed_capabilities"] = allowed_capabilities
        if allowed_csi_drivers is not None:
            self._values["allowed_csi_drivers"] = allowed_csi_drivers
        if allowed_flex_volumes is not None:
            self._values["allowed_flex_volumes"] = allowed_flex_volumes
        if allowed_host_paths is not None:
            self._values["allowed_host_paths"] = allowed_host_paths
        if allowed_proc_mount_types is not None:
            self._values["allowed_proc_mount_types"] = allowed_proc_mount_types
        if allowed_unsafe_sysctls is not None:
            self._values["allowed_unsafe_sysctls"] = allowed_unsafe_sysctls
        if allow_privilege_escalation is not None:
            self._values["allow_privilege_escalation"] = allow_privilege_escalation
        if default_add_capabilities is not None:
            self._values["default_add_capabilities"] = default_add_capabilities
        if default_allow_privilege_escalation is not None:
            self._values["default_allow_privilege_escalation"] = default_allow_privilege_escalation
        if forbidden_sysctls is not None:
            self._values["forbidden_sysctls"] = forbidden_sysctls
        if host_ipc is not None:
            self._values["host_ipc"] = host_ipc
        if host_network is not None:
            self._values["host_network"] = host_network
        if host_pid is not None:
            self._values["host_pid"] = host_pid
        if host_ports is not None:
            self._values["host_ports"] = host_ports
        if privileged is not None:
            self._values["privileged"] = privileged
        if read_only_root_filesystem is not None:
            self._values["read_only_root_filesystem"] = read_only_root_filesystem
        if required_drop_capabilities is not None:
            self._values["required_drop_capabilities"] = required_drop_capabilities
        if run_as_group is not None:
            self._values["run_as_group"] = run_as_group
        if runtime_class is not None:
            self._values["runtime_class"] = runtime_class
        if volumes is not None:
            self._values["volumes"] = volumes

    @builtins.property
    def fs_group(self) -> FsGroupStrategyOptionsV1Beta1:
        '''fsGroup is the strategy that will dictate what fs group is used by the SecurityContext.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#fsGroup
        '''
        result = self._values.get("fs_group")
        assert result is not None, "Required property 'fs_group' is missing"
        return typing.cast(FsGroupStrategyOptionsV1Beta1, result)

    @builtins.property
    def run_as_user(self) -> "RunAsUserStrategyOptionsV1Beta1":
        '''runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#runAsUser
        '''
        result = self._values.get("run_as_user")
        assert result is not None, "Required property 'run_as_user' is missing"
        return typing.cast("RunAsUserStrategyOptionsV1Beta1", result)

    @builtins.property
    def se_linux(self) -> "SeLinuxStrategyOptionsV1Beta1":
        '''seLinux is the strategy that will dictate the allowable labels that may be set.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#seLinux
        '''
        result = self._values.get("se_linux")
        assert result is not None, "Required property 'se_linux' is missing"
        return typing.cast("SeLinuxStrategyOptionsV1Beta1", result)

    @builtins.property
    def supplemental_groups(self) -> "SupplementalGroupsStrategyOptionsV1Beta1":
        '''supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#supplementalGroups
        '''
        result = self._values.get("supplemental_groups")
        assert result is not None, "Required property 'supplemental_groups' is missing"
        return typing.cast("SupplementalGroupsStrategyOptionsV1Beta1", result)

    @builtins.property
    def allowed_capabilities(self) -> typing.Optional[typing.List[builtins.str]]:
        '''allowedCapabilities is a list of capabilities that can be requested to add to the container.

        Capabilities in this field may be added at the pod author's discretion. You must not list a capability in both allowedCapabilities and requiredDropCapabilities.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowedCapabilities
        '''
        result = self._values.get("allowed_capabilities")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def allowed_csi_drivers(
        self,
    ) -> typing.Optional[typing.List[AllowedCsiDriverV1Beta1]]:
        '''AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.

        An empty value indicates that any CSI driver can be used for inline ephemeral volumes. This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowedCSIDrivers
        '''
        result = self._values.get("allowed_csi_drivers")
        return typing.cast(typing.Optional[typing.List[AllowedCsiDriverV1Beta1]], result)

    @builtins.property
    def allowed_flex_volumes(
        self,
    ) -> typing.Optional[typing.List[AllowedFlexVolumeV1Beta1]]:
        '''allowedFlexVolumes is an allowlist of Flexvolumes.

        Empty or nil indicates that all Flexvolumes may be used.  This parameter is effective only when the usage of the Flexvolumes is allowed in the "volumes" field.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowedFlexVolumes
        '''
        result = self._values.get("allowed_flex_volumes")
        return typing.cast(typing.Optional[typing.List[AllowedFlexVolumeV1Beta1]], result)

    @builtins.property
    def allowed_host_paths(
        self,
    ) -> typing.Optional[typing.List[AllowedHostPathV1Beta1]]:
        '''allowedHostPaths is an allowlist of host paths.

        Empty indicates that all host paths may be used.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowedHostPaths
        '''
        result = self._values.get("allowed_host_paths")
        return typing.cast(typing.Optional[typing.List[AllowedHostPathV1Beta1]], result)

    @builtins.property
    def allowed_proc_mount_types(self) -> typing.Optional[typing.List[builtins.str]]:
        '''AllowedProcMountTypes is an allowlist of allowed ProcMountTypes.

        Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowedProcMountTypes
        '''
        result = self._values.get("allowed_proc_mount_types")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def allowed_unsafe_sysctls(self) -> typing.Optional[typing.List[builtins.str]]:
        '''allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.

        Each entry is either a plain sysctl name or ends in "*" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all allowed unsafe sysctls explicitly to avoid rejection.

        Examples: e.g. "foo/*" allows "foo/bar", "foo/baz", etc. e.g. "foo.*" allows "foo.bar", "foo.baz", etc.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowedUnsafeSysctls
        '''
        result = self._values.get("allowed_unsafe_sysctls")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def allow_privilege_escalation(self) -> typing.Optional[builtins.bool]:
        '''allowPrivilegeEscalation determines if a pod can request to allow privilege escalation.

        If unspecified, defaults to true.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#allowPrivilegeEscalation
        '''
        result = self._values.get("allow_privilege_escalation")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def default_add_capabilities(self) -> typing.Optional[typing.List[builtins.str]]:
        '''defaultAddCapabilities is the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability.

        You may not list a capability in both defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly allowed, and need not be included in the allowedCapabilities list.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#defaultAddCapabilities
        '''
        result = self._values.get("default_add_capabilities")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def default_allow_privilege_escalation(self) -> typing.Optional[builtins.bool]:
        '''defaultAllowPrivilegeEscalation controls the default setting for whether a process can gain more privileges than its parent process.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#defaultAllowPrivilegeEscalation
        '''
        result = self._values.get("default_allow_privilege_escalation")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def forbidden_sysctls(self) -> typing.Optional[typing.List[builtins.str]]:
        '''forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none.

        Each entry is either a plain sysctl name or ends in "*" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.

        Examples: e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. e.g. "foo.*" forbids "foo.bar", "foo.baz", etc.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#forbiddenSysctls
        '''
        result = self._values.get("forbidden_sysctls")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def host_ipc(self) -> typing.Optional[builtins.bool]:
        '''hostIPC determines if the policy allows the use of HostIPC in the pod spec.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#hostIPC
        '''
        result = self._values.get("host_ipc")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def host_network(self) -> typing.Optional[builtins.bool]:
        '''hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#hostNetwork
        '''
        result = self._values.get("host_network")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def host_pid(self) -> typing.Optional[builtins.bool]:
        '''hostPID determines if the policy allows the use of HostPID in the pod spec.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#hostPID
        '''
        result = self._values.get("host_pid")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def host_ports(self) -> typing.Optional[typing.List[HostPortRangeV1Beta1]]:
        '''hostPorts determines which host port ranges are allowed to be exposed.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#hostPorts
        '''
        result = self._values.get("host_ports")
        return typing.cast(typing.Optional[typing.List[HostPortRangeV1Beta1]], result)

    @builtins.property
    def privileged(self) -> typing.Optional[builtins.bool]:
        '''privileged determines if a pod can request to be run as privileged.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#privileged
        '''
        result = self._values.get("privileged")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def read_only_root_filesystem(self) -> typing.Optional[builtins.bool]:
        '''readOnlyRootFilesystem when set to true will force containers to run with a read only root file system.

        If the container specifically requests to run with a non-read only root file system the PSP should deny the pod. If set to false the container may run with a read only root file system if it wishes but it will not be forced to.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#readOnlyRootFilesystem
        '''
        result = self._values.get("read_only_root_filesystem")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def required_drop_capabilities(self) -> typing.Optional[typing.List[builtins.str]]:
        '''requiredDropCapabilities are the capabilities that will be dropped from the container.

        These are required to be dropped and cannot be added.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#requiredDropCapabilities
        '''
        result = self._values.get("required_drop_capabilities")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def run_as_group(self) -> typing.Optional["RunAsGroupStrategyOptionsV1Beta1"]:
        '''RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set.

        If this field is omitted, the pod's RunAsGroup can take any value. This field requires the RunAsGroup feature gate to be enabled.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#runAsGroup
        '''
        result = self._values.get("run_as_group")
        return typing.cast(typing.Optional["RunAsGroupStrategyOptionsV1Beta1"], result)

    @builtins.property
    def runtime_class(self) -> typing.Optional["RuntimeClassStrategyOptionsV1Beta1"]:
        '''runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod.

        If this field is omitted, the pod's runtimeClassName field is unrestricted. Enforcement of this field depends on the RuntimeClass feature gate being enabled.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#runtimeClass
        '''
        result = self._values.get("runtime_class")
        return typing.cast(typing.Optional["RuntimeClassStrategyOptionsV1Beta1"], result)

    @builtins.property
    def volumes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''volumes is an allowlist of volume plugins.

        Empty indicates that no volumes may be used. To allow all volumes you may use '*'.

        :schema: io.k8s.api.policy.v1beta1.PodSecurityPolicySpec#volumes
        '''
        result = self._values.get("volumes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodSecurityPolicySpecV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodSpec",
    jsii_struct_bases=[],
    name_mapping={
        "containers": "containers",
        "active_deadline_seconds": "activeDeadlineSeconds",
        "affinity": "affinity",
        "automount_service_account_token": "automountServiceAccountToken",
        "dns_config": "dnsConfig",
        "dns_policy": "dnsPolicy",
        "enable_service_links": "enableServiceLinks",
        "ephemeral_containers": "ephemeralContainers",
        "host_aliases": "hostAliases",
        "host_ipc": "hostIpc",
        "hostname": "hostname",
        "host_network": "hostNetwork",
        "host_pid": "hostPid",
        "image_pull_secrets": "imagePullSecrets",
        "init_containers": "initContainers",
        "node_name": "nodeName",
        "node_selector": "nodeSelector",
        "os": "os",
        "overhead": "overhead",
        "preemption_policy": "preemptionPolicy",
        "priority": "priority",
        "priority_class_name": "priorityClassName",
        "readiness_gates": "readinessGates",
        "restart_policy": "restartPolicy",
        "runtime_class_name": "runtimeClassName",
        "scheduler_name": "schedulerName",
        "security_context": "securityContext",
        "service_account": "serviceAccount",
        "service_account_name": "serviceAccountName",
        "set_hostname_as_fqdn": "setHostnameAsFqdn",
        "share_process_namespace": "shareProcessNamespace",
        "subdomain": "subdomain",
        "termination_grace_period_seconds": "terminationGracePeriodSeconds",
        "tolerations": "tolerations",
        "topology_spread_constraints": "topologySpreadConstraints",
        "volumes": "volumes",
    },
)
class PodSpec:
    def __init__(
        self,
        *,
        containers: typing.Sequence[typing.Union[Container, typing.Dict[str, typing.Any]]],
        active_deadline_seconds: typing.Optional[jsii.Number] = None,
        affinity: typing.Optional[typing.Union[Affinity, typing.Dict[str, typing.Any]]] = None,
        automount_service_account_token: typing.Optional[builtins.bool] = None,
        dns_config: typing.Optional[typing.Union[PodDnsConfig, typing.Dict[str, typing.Any]]] = None,
        dns_policy: typing.Optional[IoK8SApiCoreV1PodSpecDnsPolicy] = None,
        enable_service_links: typing.Optional[builtins.bool] = None,
        ephemeral_containers: typing.Optional[typing.Sequence[typing.Union[EphemeralContainer, typing.Dict[str, typing.Any]]]] = None,
        host_aliases: typing.Optional[typing.Sequence[typing.Union[HostAlias, typing.Dict[str, typing.Any]]]] = None,
        host_ipc: typing.Optional[builtins.bool] = None,
        hostname: typing.Optional[builtins.str] = None,
        host_network: typing.Optional[builtins.bool] = None,
        host_pid: typing.Optional[builtins.bool] = None,
        image_pull_secrets: typing.Optional[typing.Sequence[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]]] = None,
        init_containers: typing.Optional[typing.Sequence[typing.Union[Container, typing.Dict[str, typing.Any]]]] = None,
        node_name: typing.Optional[builtins.str] = None,
        node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        os: typing.Optional[typing.Union[PodOs, typing.Dict[str, typing.Any]]] = None,
        overhead: typing.Optional[typing.Mapping[builtins.str, "Quantity"]] = None,
        preemption_policy: typing.Optional[builtins.str] = None,
        priority: typing.Optional[jsii.Number] = None,
        priority_class_name: typing.Optional[builtins.str] = None,
        readiness_gates: typing.Optional[typing.Sequence[typing.Union[PodReadinessGate, typing.Dict[str, typing.Any]]]] = None,
        restart_policy: typing.Optional[IoK8SApiCoreV1PodSpecRestartPolicy] = None,
        runtime_class_name: typing.Optional[builtins.str] = None,
        scheduler_name: typing.Optional[builtins.str] = None,
        security_context: typing.Optional[typing.Union[PodSecurityContext, typing.Dict[str, typing.Any]]] = None,
        service_account: typing.Optional[builtins.str] = None,
        service_account_name: typing.Optional[builtins.str] = None,
        set_hostname_as_fqdn: typing.Optional[builtins.bool] = None,
        share_process_namespace: typing.Optional[builtins.bool] = None,
        subdomain: typing.Optional[builtins.str] = None,
        termination_grace_period_seconds: typing.Optional[jsii.Number] = None,
        tolerations: typing.Optional[typing.Sequence[typing.Union["Toleration", typing.Dict[str, typing.Any]]]] = None,
        topology_spread_constraints: typing.Optional[typing.Sequence[typing.Union["TopologySpreadConstraint", typing.Dict[str, typing.Any]]]] = None,
        volumes: typing.Optional[typing.Sequence[typing.Union["Volume", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''PodSpec is a description of a pod.

        :param containers: List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.
        :param active_deadline_seconds: Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.
        :param affinity: If specified, the pod's scheduling constraints.
        :param automount_service_account_token: AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.
        :param dns_config: Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.
        :param dns_policy: Set DNS policy for the pod. Defaults to "ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'. Possible enum values: - ``"ClusterFirst"`` indicates that the pod should use cluster DNS first unless hostNetwork is true, if it is available, then fall back on the default (as determined by kubelet) DNS settings. - ``"ClusterFirstWithHostNet"`` indicates that the pod should use cluster DNS first, if it is available, then fall back on the default (as determined by kubelet) DNS settings. - ``"Default"`` indicates that the pod should use the default (as determined by kubelet) DNS settings. - ``"None"`` indicates that the pod should use empty DNS settings. DNS parameters such as nameservers and search paths should be defined via DNSConfig. Default: ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.
        :param enable_service_links: EnableServiceLinks indicates whether information about services should be injected into pod's environment variables, matching the syntax of Docker links. Optional: Defaults to true. Default: true.
        :param ephemeral_containers: List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.
        :param host_aliases: HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.
        :param host_ipc: Use the host's ipc namespace. Optional: Default to false. Default: false.
        :param hostname: Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value.
        :param host_network: Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false. Default: false.
        :param host_pid: Use the host's pid namespace. Optional: Default to false. Default: false.
        :param image_pull_secrets: ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
        :param init_containers: List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
        :param node_name: NodeName is a request to schedule this pod onto a specific node. If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements.
        :param node_selector: NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
        :param os: Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set. If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is an alpha field and requires the IdentifyPodOS feature
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
        :param preemption_policy: PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate. Default: PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.
        :param priority: The priority value. Various system components use this field to find the priority of the pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.
        :param priority_class_name: If specified, indicates the pod's priority. "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.
        :param readiness_gates: If specified, all readiness gates will be evaluated for pod readiness. A pod is ready when all its containers are ready AND all conditions specified in the readiness gates have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates
        :param restart_policy: Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy. Possible enum values: - ``"Always"`` - ``"Never"`` - ``"OnFailure"`` Default: Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
        :param runtime_class_name: RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class This is a beta feature as of Kubernetes v1.14.
        :param scheduler_name: If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.
        :param security_context: SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. Default: empty. See type description for default values of each field.
        :param service_account: DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. Deprecated: Use serviceAccountName instead.
        :param service_account_name: ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
        :param set_hostname_as_fqdn: If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false. Default: false.
        :param share_process_namespace: Share a single process namespace between all of the containers in a pod. When this is set containers will be able to view and signal processes from other containers in the same pod, and the first process in each container will not be assigned PID 1. HostPID and ShareProcessNamespace cannot both be set. Optional: Default to false. Default: false.
        :param subdomain: If specified, the fully qualified Pod hostname will be "...svc.". If not specified, the pod will not have a domainname at all.
        :param termination_grace_period_seconds: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds. Default: 30 seconds.
        :param tolerations: If specified, the pod's tolerations.
        :param topology_spread_constraints: TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.
        :param volumes: List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes

        :schema: io.k8s.api.core.v1.PodSpec
        '''
        if isinstance(affinity, dict):
            affinity = Affinity(**affinity)
        if isinstance(dns_config, dict):
            dns_config = PodDnsConfig(**dns_config)
        if isinstance(os, dict):
            os = PodOs(**os)
        if isinstance(security_context, dict):
            security_context = PodSecurityContext(**security_context)
        if __debug__:
            def stub(
                *,
                containers: typing.Sequence[typing.Union[Container, typing.Dict[str, typing.Any]]],
                active_deadline_seconds: typing.Optional[jsii.Number] = None,
                affinity: typing.Optional[typing.Union[Affinity, typing.Dict[str, typing.Any]]] = None,
                automount_service_account_token: typing.Optional[builtins.bool] = None,
                dns_config: typing.Optional[typing.Union[PodDnsConfig, typing.Dict[str, typing.Any]]] = None,
                dns_policy: typing.Optional[IoK8SApiCoreV1PodSpecDnsPolicy] = None,
                enable_service_links: typing.Optional[builtins.bool] = None,
                ephemeral_containers: typing.Optional[typing.Sequence[typing.Union[EphemeralContainer, typing.Dict[str, typing.Any]]]] = None,
                host_aliases: typing.Optional[typing.Sequence[typing.Union[HostAlias, typing.Dict[str, typing.Any]]]] = None,
                host_ipc: typing.Optional[builtins.bool] = None,
                hostname: typing.Optional[builtins.str] = None,
                host_network: typing.Optional[builtins.bool] = None,
                host_pid: typing.Optional[builtins.bool] = None,
                image_pull_secrets: typing.Optional[typing.Sequence[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]]] = None,
                init_containers: typing.Optional[typing.Sequence[typing.Union[Container, typing.Dict[str, typing.Any]]]] = None,
                node_name: typing.Optional[builtins.str] = None,
                node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                os: typing.Optional[typing.Union[PodOs, typing.Dict[str, typing.Any]]] = None,
                overhead: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                preemption_policy: typing.Optional[builtins.str] = None,
                priority: typing.Optional[jsii.Number] = None,
                priority_class_name: typing.Optional[builtins.str] = None,
                readiness_gates: typing.Optional[typing.Sequence[typing.Union[PodReadinessGate, typing.Dict[str, typing.Any]]]] = None,
                restart_policy: typing.Optional[IoK8SApiCoreV1PodSpecRestartPolicy] = None,
                runtime_class_name: typing.Optional[builtins.str] = None,
                scheduler_name: typing.Optional[builtins.str] = None,
                security_context: typing.Optional[typing.Union[PodSecurityContext, typing.Dict[str, typing.Any]]] = None,
                service_account: typing.Optional[builtins.str] = None,
                service_account_name: typing.Optional[builtins.str] = None,
                set_hostname_as_fqdn: typing.Optional[builtins.bool] = None,
                share_process_namespace: typing.Optional[builtins.bool] = None,
                subdomain: typing.Optional[builtins.str] = None,
                termination_grace_period_seconds: typing.Optional[jsii.Number] = None,
                tolerations: typing.Optional[typing.Sequence[typing.Union[Toleration, typing.Dict[str, typing.Any]]]] = None,
                topology_spread_constraints: typing.Optional[typing.Sequence[typing.Union[TopologySpreadConstraint, typing.Dict[str, typing.Any]]]] = None,
                volumes: typing.Optional[typing.Sequence[typing.Union[Volume, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument containers", value=containers, expected_type=type_hints["containers"])
            check_type(argname="argument active_deadline_seconds", value=active_deadline_seconds, expected_type=type_hints["active_deadline_seconds"])
            check_type(argname="argument affinity", value=affinity, expected_type=type_hints["affinity"])
            check_type(argname="argument automount_service_account_token", value=automount_service_account_token, expected_type=type_hints["automount_service_account_token"])
            check_type(argname="argument dns_config", value=dns_config, expected_type=type_hints["dns_config"])
            check_type(argname="argument dns_policy", value=dns_policy, expected_type=type_hints["dns_policy"])
            check_type(argname="argument enable_service_links", value=enable_service_links, expected_type=type_hints["enable_service_links"])
            check_type(argname="argument ephemeral_containers", value=ephemeral_containers, expected_type=type_hints["ephemeral_containers"])
            check_type(argname="argument host_aliases", value=host_aliases, expected_type=type_hints["host_aliases"])
            check_type(argname="argument host_ipc", value=host_ipc, expected_type=type_hints["host_ipc"])
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument host_network", value=host_network, expected_type=type_hints["host_network"])
            check_type(argname="argument host_pid", value=host_pid, expected_type=type_hints["host_pid"])
            check_type(argname="argument image_pull_secrets", value=image_pull_secrets, expected_type=type_hints["image_pull_secrets"])
            check_type(argname="argument init_containers", value=init_containers, expected_type=type_hints["init_containers"])
            check_type(argname="argument node_name", value=node_name, expected_type=type_hints["node_name"])
            check_type(argname="argument node_selector", value=node_selector, expected_type=type_hints["node_selector"])
            check_type(argname="argument os", value=os, expected_type=type_hints["os"])
            check_type(argname="argument overhead", value=overhead, expected_type=type_hints["overhead"])
            check_type(argname="argument preemption_policy", value=preemption_policy, expected_type=type_hints["preemption_policy"])
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument priority_class_name", value=priority_class_name, expected_type=type_hints["priority_class_name"])
            check_type(argname="argument readiness_gates", value=readiness_gates, expected_type=type_hints["readiness_gates"])
            check_type(argname="argument restart_policy", value=restart_policy, expected_type=type_hints["restart_policy"])
            check_type(argname="argument runtime_class_name", value=runtime_class_name, expected_type=type_hints["runtime_class_name"])
            check_type(argname="argument scheduler_name", value=scheduler_name, expected_type=type_hints["scheduler_name"])
            check_type(argname="argument security_context", value=security_context, expected_type=type_hints["security_context"])
            check_type(argname="argument service_account", value=service_account, expected_type=type_hints["service_account"])
            check_type(argname="argument service_account_name", value=service_account_name, expected_type=type_hints["service_account_name"])
            check_type(argname="argument set_hostname_as_fqdn", value=set_hostname_as_fqdn, expected_type=type_hints["set_hostname_as_fqdn"])
            check_type(argname="argument share_process_namespace", value=share_process_namespace, expected_type=type_hints["share_process_namespace"])
            check_type(argname="argument subdomain", value=subdomain, expected_type=type_hints["subdomain"])
            check_type(argname="argument termination_grace_period_seconds", value=termination_grace_period_seconds, expected_type=type_hints["termination_grace_period_seconds"])
            check_type(argname="argument tolerations", value=tolerations, expected_type=type_hints["tolerations"])
            check_type(argname="argument topology_spread_constraints", value=topology_spread_constraints, expected_type=type_hints["topology_spread_constraints"])
            check_type(argname="argument volumes", value=volumes, expected_type=type_hints["volumes"])
        self._values: typing.Dict[str, typing.Any] = {
            "containers": containers,
        }
        if active_deadline_seconds is not None:
            self._values["active_deadline_seconds"] = active_deadline_seconds
        if affinity is not None:
            self._values["affinity"] = affinity
        if automount_service_account_token is not None:
            self._values["automount_service_account_token"] = automount_service_account_token
        if dns_config is not None:
            self._values["dns_config"] = dns_config
        if dns_policy is not None:
            self._values["dns_policy"] = dns_policy
        if enable_service_links is not None:
            self._values["enable_service_links"] = enable_service_links
        if ephemeral_containers is not None:
            self._values["ephemeral_containers"] = ephemeral_containers
        if host_aliases is not None:
            self._values["host_aliases"] = host_aliases
        if host_ipc is not None:
            self._values["host_ipc"] = host_ipc
        if hostname is not None:
            self._values["hostname"] = hostname
        if host_network is not None:
            self._values["host_network"] = host_network
        if host_pid is not None:
            self._values["host_pid"] = host_pid
        if image_pull_secrets is not None:
            self._values["image_pull_secrets"] = image_pull_secrets
        if init_containers is not None:
            self._values["init_containers"] = init_containers
        if node_name is not None:
            self._values["node_name"] = node_name
        if node_selector is not None:
            self._values["node_selector"] = node_selector
        if os is not None:
            self._values["os"] = os
        if overhead is not None:
            self._values["overhead"] = overhead
        if preemption_policy is not None:
            self._values["preemption_policy"] = preemption_policy
        if priority is not None:
            self._values["priority"] = priority
        if priority_class_name is not None:
            self._values["priority_class_name"] = priority_class_name
        if readiness_gates is not None:
            self._values["readiness_gates"] = readiness_gates
        if restart_policy is not None:
            self._values["restart_policy"] = restart_policy
        if runtime_class_name is not None:
            self._values["runtime_class_name"] = runtime_class_name
        if scheduler_name is not None:
            self._values["scheduler_name"] = scheduler_name
        if security_context is not None:
            self._values["security_context"] = security_context
        if service_account is not None:
            self._values["service_account"] = service_account
        if service_account_name is not None:
            self._values["service_account_name"] = service_account_name
        if set_hostname_as_fqdn is not None:
            self._values["set_hostname_as_fqdn"] = set_hostname_as_fqdn
        if share_process_namespace is not None:
            self._values["share_process_namespace"] = share_process_namespace
        if subdomain is not None:
            self._values["subdomain"] = subdomain
        if termination_grace_period_seconds is not None:
            self._values["termination_grace_period_seconds"] = termination_grace_period_seconds
        if tolerations is not None:
            self._values["tolerations"] = tolerations
        if topology_spread_constraints is not None:
            self._values["topology_spread_constraints"] = topology_spread_constraints
        if volumes is not None:
            self._values["volumes"] = volumes

    @builtins.property
    def containers(self) -> typing.List[Container]:
        '''List of containers belonging to the pod.

        Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.

        :schema: io.k8s.api.core.v1.PodSpec#containers
        '''
        result = self._values.get("containers")
        assert result is not None, "Required property 'containers' is missing"
        return typing.cast(typing.List[Container], result)

    @builtins.property
    def active_deadline_seconds(self) -> typing.Optional[jsii.Number]:
        '''Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers.

        Value must be a positive integer.

        :schema: io.k8s.api.core.v1.PodSpec#activeDeadlineSeconds
        '''
        result = self._values.get("active_deadline_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def affinity(self) -> typing.Optional[Affinity]:
        '''If specified, the pod's scheduling constraints.

        :schema: io.k8s.api.core.v1.PodSpec#affinity
        '''
        result = self._values.get("affinity")
        return typing.cast(typing.Optional[Affinity], result)

    @builtins.property
    def automount_service_account_token(self) -> typing.Optional[builtins.bool]:
        '''AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.

        :schema: io.k8s.api.core.v1.PodSpec#automountServiceAccountToken
        '''
        result = self._values.get("automount_service_account_token")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def dns_config(self) -> typing.Optional[PodDnsConfig]:
        '''Specifies the DNS parameters of a pod.

        Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.

        :schema: io.k8s.api.core.v1.PodSpec#dnsConfig
        '''
        result = self._values.get("dns_config")
        return typing.cast(typing.Optional[PodDnsConfig], result)

    @builtins.property
    def dns_policy(self) -> typing.Optional[IoK8SApiCoreV1PodSpecDnsPolicy]:
        '''Set DNS policy for the pod.

        Defaults to "ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.

        Possible enum values:

        - ``"ClusterFirst"`` indicates that the pod should use cluster DNS first unless hostNetwork is true, if it is available, then fall back on the default (as determined by kubelet) DNS settings.
        - ``"ClusterFirstWithHostNet"`` indicates that the pod should use cluster DNS first, if it is available, then fall back on the default (as determined by kubelet) DNS settings.
        - ``"Default"`` indicates that the pod should use the default (as determined by kubelet) DNS settings.
        - ``"None"`` indicates that the pod should use empty DNS settings. DNS parameters such as nameservers and search paths should be defined via DNSConfig.

        :default: ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.

        :schema: io.k8s.api.core.v1.PodSpec#dnsPolicy
        '''
        result = self._values.get("dns_policy")
        return typing.cast(typing.Optional[IoK8SApiCoreV1PodSpecDnsPolicy], result)

    @builtins.property
    def enable_service_links(self) -> typing.Optional[builtins.bool]:
        '''EnableServiceLinks indicates whether information about services should be injected into pod's environment variables, matching the syntax of Docker links.

        Optional: Defaults to true.

        :default: true.

        :schema: io.k8s.api.core.v1.PodSpec#enableServiceLinks
        '''
        result = self._values.get("enable_service_links")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ephemeral_containers(self) -> typing.Optional[typing.List[EphemeralContainer]]:
        '''List of ephemeral containers run in this pod.

        Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.

        :schema: io.k8s.api.core.v1.PodSpec#ephemeralContainers
        '''
        result = self._values.get("ephemeral_containers")
        return typing.cast(typing.Optional[typing.List[EphemeralContainer]], result)

    @builtins.property
    def host_aliases(self) -> typing.Optional[typing.List[HostAlias]]:
        '''HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified.

        This is only valid for non-hostNetwork pods.

        :schema: io.k8s.api.core.v1.PodSpec#hostAliases
        '''
        result = self._values.get("host_aliases")
        return typing.cast(typing.Optional[typing.List[HostAlias]], result)

    @builtins.property
    def host_ipc(self) -> typing.Optional[builtins.bool]:
        '''Use the host's ipc namespace.

        Optional: Default to false.

        :default: false.

        :schema: io.k8s.api.core.v1.PodSpec#hostIPC
        '''
        result = self._values.get("host_ipc")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def hostname(self) -> typing.Optional[builtins.str]:
        '''Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value.

        :schema: io.k8s.api.core.v1.PodSpec#hostname
        '''
        result = self._values.get("hostname")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def host_network(self) -> typing.Optional[builtins.bool]:
        '''Host networking requested for this pod.

        Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false.

        :default: false.

        :schema: io.k8s.api.core.v1.PodSpec#hostNetwork
        '''
        result = self._values.get("host_network")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def host_pid(self) -> typing.Optional[builtins.bool]:
        '''Use the host's pid namespace.

        Optional: Default to false.

        :default: false.

        :schema: io.k8s.api.core.v1.PodSpec#hostPID
        '''
        result = self._values.get("host_pid")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def image_pull_secrets(self) -> typing.Optional[typing.List[LocalObjectReference]]:
        '''ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.

        If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod

        :schema: io.k8s.api.core.v1.PodSpec#imagePullSecrets
        '''
        result = self._values.get("image_pull_secrets")
        return typing.cast(typing.Optional[typing.List[LocalObjectReference]], result)

    @builtins.property
    def init_containers(self) -> typing.Optional[typing.List[Container]]:
        '''List of initialization containers belonging to the pod.

        Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

        :schema: io.k8s.api.core.v1.PodSpec#initContainers
        '''
        result = self._values.get("init_containers")
        return typing.cast(typing.Optional[typing.List[Container]], result)

    @builtins.property
    def node_name(self) -> typing.Optional[builtins.str]:
        '''NodeName is a request to schedule this pod onto a specific node.

        If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements.

        :schema: io.k8s.api.core.v1.PodSpec#nodeName
        '''
        result = self._values.get("node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_selector(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''NodeSelector is a selector which must be true for the pod to fit on a node.

        Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

        :schema: io.k8s.api.core.v1.PodSpec#nodeSelector
        '''
        result = self._values.get("node_selector")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def os(self) -> typing.Optional[PodOs]:
        '''Specifies the OS of the containers in the pod.

        Some pod and container fields are restricted if this is set.

        If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions

        If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is an alpha field and requires the IdentifyPodOS feature

        :schema: io.k8s.api.core.v1.PodSpec#os
        '''
        result = self._values.get("os")
        return typing.cast(typing.Optional[PodOs], result)

    @builtins.property
    def overhead(self) -> typing.Optional[typing.Mapping[builtins.str, "Quantity"]]:
        '''Overhead represents the resource overhead associated with running a pod for a given RuntimeClass.

        This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.

        :schema: io.k8s.api.core.v1.PodSpec#overhead
        '''
        result = self._values.get("overhead")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "Quantity"]], result)

    @builtins.property
    def preemption_policy(self) -> typing.Optional[builtins.str]:
        '''PreemptionPolicy is the Policy for preempting pods with lower priority.

        One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.

        :default: PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.

        :schema: io.k8s.api.core.v1.PodSpec#preemptionPolicy
        '''
        result = self._values.get("preemption_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority value.

        Various system components use this field to find the priority of the pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.

        :schema: io.k8s.api.core.v1.PodSpec#priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def priority_class_name(self) -> typing.Optional[builtins.str]:
        '''If specified, indicates the pod's priority.

        "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.

        :schema: io.k8s.api.core.v1.PodSpec#priorityClassName
        '''
        result = self._values.get("priority_class_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def readiness_gates(self) -> typing.Optional[typing.List[PodReadinessGate]]:
        '''If specified, all readiness gates will be evaluated for pod readiness.

        A pod is ready when all its containers are ready AND all conditions specified in the readiness gates have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates

        :schema: io.k8s.api.core.v1.PodSpec#readinessGates
        '''
        result = self._values.get("readiness_gates")
        return typing.cast(typing.Optional[typing.List[PodReadinessGate]], result)

    @builtins.property
    def restart_policy(self) -> typing.Optional[IoK8SApiCoreV1PodSpecRestartPolicy]:
        '''Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy.

        Possible enum values:

        - ``"Always"``
        - ``"Never"``
        - ``"OnFailure"``

        :default: Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy

        :schema: io.k8s.api.core.v1.PodSpec#restartPolicy
        '''
        result = self._values.get("restart_policy")
        return typing.cast(typing.Optional[IoK8SApiCoreV1PodSpecRestartPolicy], result)

    @builtins.property
    def runtime_class_name(self) -> typing.Optional[builtins.str]:
        '''RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.  If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class This is a beta feature as of Kubernetes v1.14.

        :schema: io.k8s.api.core.v1.PodSpec#runtimeClassName
        '''
        result = self._values.get("runtime_class_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def scheduler_name(self) -> typing.Optional[builtins.str]:
        '''If specified, the pod will be dispatched by specified scheduler.

        If not specified, the pod will be dispatched by default scheduler.

        :schema: io.k8s.api.core.v1.PodSpec#schedulerName
        '''
        result = self._values.get("scheduler_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def security_context(self) -> typing.Optional[PodSecurityContext]:
        '''SecurityContext holds pod-level security attributes and common container settings.

        Optional: Defaults to empty.  See type description for default values of each field.

        :default: empty.  See type description for default values of each field.

        :schema: io.k8s.api.core.v1.PodSpec#securityContext
        '''
        result = self._values.get("security_context")
        return typing.cast(typing.Optional[PodSecurityContext], result)

    @builtins.property
    def service_account(self) -> typing.Optional[builtins.str]:
        '''DeprecatedServiceAccount is a depreciated alias for ServiceAccountName.

        Deprecated: Use serviceAccountName instead.

        :schema: io.k8s.api.core.v1.PodSpec#serviceAccount
        '''
        result = self._values.get("service_account")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service_account_name(self) -> typing.Optional[builtins.str]:
        '''ServiceAccountName is the name of the ServiceAccount to use to run this pod.

        More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

        :schema: io.k8s.api.core.v1.PodSpec#serviceAccountName
        '''
        result = self._values.get("service_account_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def set_hostname_as_fqdn(self) -> typing.Optional[builtins.bool]:
        '''If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default).

        In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false.

        :default: false.

        :schema: io.k8s.api.core.v1.PodSpec#setHostnameAsFQDN
        '''
        result = self._values.get("set_hostname_as_fqdn")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def share_process_namespace(self) -> typing.Optional[builtins.bool]:
        '''Share a single process namespace between all of the containers in a pod.

        When this is set containers will be able to view and signal processes from other containers in the same pod, and the first process in each container will not be assigned PID 1. HostPID and ShareProcessNamespace cannot both be set. Optional: Default to false.

        :default: false.

        :schema: io.k8s.api.core.v1.PodSpec#shareProcessNamespace
        '''
        result = self._values.get("share_process_namespace")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def subdomain(self) -> typing.Optional[builtins.str]:
        '''If specified, the fully qualified Pod hostname will be "...svc.". If not specified, the pod will not have a domainname at all.

        :schema: io.k8s.api.core.v1.PodSpec#subdomain
        '''
        result = self._values.get("subdomain")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def termination_grace_period_seconds(self) -> typing.Optional[jsii.Number]:
        '''Optional duration in seconds the pod needs to terminate gracefully.

        May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.

        :default: 30 seconds.

        :schema: io.k8s.api.core.v1.PodSpec#terminationGracePeriodSeconds
        '''
        result = self._values.get("termination_grace_period_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tolerations(self) -> typing.Optional[typing.List["Toleration"]]:
        '''If specified, the pod's tolerations.

        :schema: io.k8s.api.core.v1.PodSpec#tolerations
        '''
        result = self._values.get("tolerations")
        return typing.cast(typing.Optional[typing.List["Toleration"]], result)

    @builtins.property
    def topology_spread_constraints(
        self,
    ) -> typing.Optional[typing.List["TopologySpreadConstraint"]]:
        '''TopologySpreadConstraints describes how a group of pods ought to spread across topology domains.

        Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.

        :schema: io.k8s.api.core.v1.PodSpec#topologySpreadConstraints
        '''
        result = self._values.get("topology_spread_constraints")
        return typing.cast(typing.Optional[typing.List["TopologySpreadConstraint"]], result)

    @builtins.property
    def volumes(self) -> typing.Optional[typing.List["Volume"]]:
        '''List of volumes that can be mounted by containers belonging to the pod.

        More info: https://kubernetes.io/docs/concepts/storage/volumes

        :schema: io.k8s.api.core.v1.PodSpec#volumes
        '''
        result = self._values.get("volumes")
        return typing.cast(typing.Optional[typing.List["Volume"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodTemplateSpec",
    jsii_struct_bases=[],
    name_mapping={"metadata": "metadata", "spec": "spec"},
)
class PodTemplateSpec:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
        spec: typing.Optional[typing.Union[PodSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodTemplateSpec describes the data a pod should have when created from a template.

        :param metadata: Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        :param spec: Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.PodTemplateSpec
        '''
        if isinstance(metadata, dict):
            metadata = ObjectMeta(**metadata)
        if isinstance(spec, dict):
            spec = PodSpec(**spec)
        if __debug__:
            def stub(
                *,
                metadata: typing.Optional[typing.Union[ObjectMeta, typing.Dict[str, typing.Any]]] = None,
                spec: typing.Optional[typing.Union[PodSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if spec is not None:
            self._values["spec"] = spec

    @builtins.property
    def metadata(self) -> typing.Optional[ObjectMeta]:
        '''Standard object's metadata.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

        :schema: io.k8s.api.core.v1.PodTemplateSpec#metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional[ObjectMeta], result)

    @builtins.property
    def spec(self) -> typing.Optional[PodSpec]:
        '''Specification of the desired behavior of the pod.

        More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

        :schema: io.k8s.api.core.v1.PodTemplateSpec#spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[PodSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodTemplateSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodsMetricSourceV2",
    jsii_struct_bases=[],
    name_mapping={"metric": "metric", "target": "target"},
)
class PodsMetricSourceV2:
    def __init__(
        self,
        *,
        metric: typing.Union[MetricIdentifierV2, typing.Dict[str, typing.Any]],
        target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
    ) -> None:
        '''PodsMetricSource indicates how to scale on 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.

        :param metric: metric identifies the target metric by name and selector.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.PodsMetricSource
        '''
        if isinstance(metric, dict):
            metric = MetricIdentifierV2(**metric)
        if isinstance(target, dict):
            target = MetricTargetV2(**target)
        if __debug__:
            def stub(
                *,
                metric: typing.Union[MetricIdentifierV2, typing.Dict[str, typing.Any]],
                target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric", value=metric, expected_type=type_hints["metric"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric": metric,
            "target": target,
        }

    @builtins.property
    def metric(self) -> MetricIdentifierV2:
        '''metric identifies the target metric by name and selector.

        :schema: io.k8s.api.autoscaling.v2.PodsMetricSource#metric
        '''
        result = self._values.get("metric")
        assert result is not None, "Required property 'metric' is missing"
        return typing.cast(MetricIdentifierV2, result)

    @builtins.property
    def target(self) -> MetricTargetV2:
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.PodsMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(MetricTargetV2, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodsMetricSourceV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodsMetricSourceV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "metric_name": "metricName",
        "target_average_value": "targetAverageValue",
        "selector": "selector",
    },
)
class PodsMetricSourceV2Beta1:
    def __init__(
        self,
        *,
        metric_name: builtins.str,
        target_average_value: "Quantity",
        selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PodsMetricSource indicates how to scale on 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.

        :param metric_name: metricName is the name of the metric in question.
        :param target_average_value: targetAverageValue is the target value of the average of the metric across all relevant pods (as a quantity).
        :param selector: 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.

        :schema: io.k8s.api.autoscaling.v2beta1.PodsMetricSource
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if __debug__:
            def stub(
                *,
                metric_name: builtins.str,
                target_average_value: Quantity,
                selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric_name", value=metric_name, expected_type=type_hints["metric_name"])
            check_type(argname="argument target_average_value", value=target_average_value, expected_type=type_hints["target_average_value"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric_name": metric_name,
            "target_average_value": target_average_value,
        }
        if selector is not None:
            self._values["selector"] = selector

    @builtins.property
    def metric_name(self) -> builtins.str:
        '''metricName is the name of the metric in question.

        :schema: io.k8s.api.autoscaling.v2beta1.PodsMetricSource#metricName
        '''
        result = self._values.get("metric_name")
        assert result is not None, "Required property 'metric_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target_average_value(self) -> "Quantity":
        '''targetAverageValue is the target value of the average of the metric across all relevant pods (as a quantity).

        :schema: io.k8s.api.autoscaling.v2beta1.PodsMetricSource#targetAverageValue
        '''
        result = self._values.get("target_average_value")
        assert result is not None, "Required property 'target_average_value' is missing"
        return typing.cast("Quantity", result)

    @builtins.property
    def selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :schema: io.k8s.api.autoscaling.v2beta1.PodsMetricSource#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodsMetricSourceV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PodsMetricSourceV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"metric": "metric", "target": "target"},
)
class PodsMetricSourceV2Beta2:
    def __init__(
        self,
        *,
        metric: typing.Union[MetricIdentifierV2Beta2, typing.Dict[str, typing.Any]],
        target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
    ) -> None:
        '''PodsMetricSource indicates how to scale on 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.

        :param metric: metric identifies the target metric by name and selector.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.PodsMetricSource
        '''
        if isinstance(metric, dict):
            metric = MetricIdentifierV2Beta2(**metric)
        if isinstance(target, dict):
            target = MetricTargetV2Beta2(**target)
        if __debug__:
            def stub(
                *,
                metric: typing.Union[MetricIdentifierV2Beta2, typing.Dict[str, typing.Any]],
                target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument metric", value=metric, expected_type=type_hints["metric"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "metric": metric,
            "target": target,
        }

    @builtins.property
    def metric(self) -> MetricIdentifierV2Beta2:
        '''metric identifies the target metric by name and selector.

        :schema: io.k8s.api.autoscaling.v2beta2.PodsMetricSource#metric
        '''
        result = self._values.get("metric")
        assert result is not None, "Required property 'metric' is missing"
        return typing.cast(MetricIdentifierV2Beta2, result)

    @builtins.property
    def target(self) -> MetricTargetV2Beta2:
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.PodsMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(MetricTargetV2Beta2, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PodsMetricSourceV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PolicyRule",
    jsii_struct_bases=[],
    name_mapping={
        "verbs": "verbs",
        "api_groups": "apiGroups",
        "non_resource_ur_ls": "nonResourceUrLs",
        "resource_names": "resourceNames",
        "resources": "resources",
    },
)
class PolicyRule:
    def __init__(
        self,
        *,
        verbs: typing.Sequence[builtins.str],
        api_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
        non_resource_ur_ls: typing.Optional[typing.Sequence[builtins.str]] = None,
        resource_names: typing.Optional[typing.Sequence[builtins.str]] = None,
        resources: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.

        :param verbs: Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.
        :param api_groups: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.
        :param non_resource_ur_ls: NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
        :param resource_names: ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
        :param resources: Resources is a list of resources this rule applies to. '*' represents all resources.

        :schema: io.k8s.api.rbac.v1.PolicyRule
        '''
        if __debug__:
            def stub(
                *,
                verbs: typing.Sequence[builtins.str],
                api_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
                non_resource_ur_ls: typing.Optional[typing.Sequence[builtins.str]] = None,
                resource_names: typing.Optional[typing.Sequence[builtins.str]] = None,
                resources: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument verbs", value=verbs, expected_type=type_hints["verbs"])
            check_type(argname="argument api_groups", value=api_groups, expected_type=type_hints["api_groups"])
            check_type(argname="argument non_resource_ur_ls", value=non_resource_ur_ls, expected_type=type_hints["non_resource_ur_ls"])
            check_type(argname="argument resource_names", value=resource_names, expected_type=type_hints["resource_names"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
        self._values: typing.Dict[str, typing.Any] = {
            "verbs": verbs,
        }
        if api_groups is not None:
            self._values["api_groups"] = api_groups
        if non_resource_ur_ls is not None:
            self._values["non_resource_ur_ls"] = non_resource_ur_ls
        if resource_names is not None:
            self._values["resource_names"] = resource_names
        if resources is not None:
            self._values["resources"] = resources

    @builtins.property
    def verbs(self) -> typing.List[builtins.str]:
        '''Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule.

        '*' represents all verbs.

        :schema: io.k8s.api.rbac.v1.PolicyRule#verbs
        '''
        result = self._values.get("verbs")
        assert result is not None, "Required property 'verbs' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def api_groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''APIGroups is the name of the APIGroup that contains the resources.

        If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.

        :schema: io.k8s.api.rbac.v1.PolicyRule#apiGroups
        '''
        result = self._values.get("api_groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def non_resource_ur_ls(self) -> typing.Optional[typing.List[builtins.str]]:
        '''NonResourceURLs is a set of partial urls that a user should have access to.

        *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"),  but not both.

        :schema: io.k8s.api.rbac.v1.PolicyRule#nonResourceURLs
        '''
        result = self._values.get("non_resource_ur_ls")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def resource_names(self) -> typing.Optional[typing.List[builtins.str]]:
        '''ResourceNames is an optional white list of names that the rule applies to.

        An empty set means that everything is allowed.

        :schema: io.k8s.api.rbac.v1.PolicyRule#resourceNames
        '''
        result = self._values.get("resource_names")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def resources(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Resources is a list of resources this rule applies to.

        '*' represents all resources.

        :schema: io.k8s.api.rbac.v1.PolicyRule#resources
        '''
        result = self._values.get("resources")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PolicyRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PolicyRulesWithSubjectsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "subjects": "subjects",
        "non_resource_rules": "nonResourceRules",
        "resource_rules": "resourceRules",
    },
)
class PolicyRulesWithSubjectsV1Beta1:
    def __init__(
        self,
        *,
        subjects: typing.Sequence[typing.Union["SubjectV1Beta1", typing.Dict[str, typing.Any]]],
        non_resource_rules: typing.Optional[typing.Sequence[typing.Union[NonResourcePolicyRuleV1Beta1, typing.Dict[str, typing.Any]]]] = None,
        resource_rules: typing.Optional[typing.Sequence[typing.Union["ResourcePolicyRuleV1Beta1", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''PolicyRulesWithSubjects prescribes a test that applies to a request to an apiserver.

        The test considers the subject making the request, the verb being requested, and the resource to be acted upon. This PolicyRulesWithSubjects matches a request if and only if both (a) at least one member of subjects matches the request and (b) at least one member of resourceRules or nonResourceRules matches the request.

        :param subjects: subjects is the list of normal user, serviceaccount, or group that this rule cares about. There must be at least one member in this slice. A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. Required.
        :param non_resource_rules: ``nonResourceRules`` is a list of NonResourcePolicyRules that identify matching requests according to their verb and the target non-resource URL.
        :param resource_rules: ``resourceRules`` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the target resource. At least one of ``resourceRules`` and ``nonResourceRules`` has to be non-empty.

        :schema: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects
        '''
        if __debug__:
            def stub(
                *,
                subjects: typing.Sequence[typing.Union[SubjectV1Beta1, typing.Dict[str, typing.Any]]],
                non_resource_rules: typing.Optional[typing.Sequence[typing.Union[NonResourcePolicyRuleV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                resource_rules: typing.Optional[typing.Sequence[typing.Union[ResourcePolicyRuleV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument subjects", value=subjects, expected_type=type_hints["subjects"])
            check_type(argname="argument non_resource_rules", value=non_resource_rules, expected_type=type_hints["non_resource_rules"])
            check_type(argname="argument resource_rules", value=resource_rules, expected_type=type_hints["resource_rules"])
        self._values: typing.Dict[str, typing.Any] = {
            "subjects": subjects,
        }
        if non_resource_rules is not None:
            self._values["non_resource_rules"] = non_resource_rules
        if resource_rules is not None:
            self._values["resource_rules"] = resource_rules

    @builtins.property
    def subjects(self) -> typing.List["SubjectV1Beta1"]:
        '''subjects is the list of normal user, serviceaccount, or group that this rule cares about.

        There must be at least one member in this slice. A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects#subjects
        '''
        result = self._values.get("subjects")
        assert result is not None, "Required property 'subjects' is missing"
        return typing.cast(typing.List["SubjectV1Beta1"], result)

    @builtins.property
    def non_resource_rules(
        self,
    ) -> typing.Optional[typing.List[NonResourcePolicyRuleV1Beta1]]:
        '''``nonResourceRules`` is a list of NonResourcePolicyRules that identify matching requests according to their verb and the target non-resource URL.

        :schema: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects#nonResourceRules
        '''
        result = self._values.get("non_resource_rules")
        return typing.cast(typing.Optional[typing.List[NonResourcePolicyRuleV1Beta1]], result)

    @builtins.property
    def resource_rules(
        self,
    ) -> typing.Optional[typing.List["ResourcePolicyRuleV1Beta1"]]:
        '''``resourceRules`` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the target resource.

        At least one of ``resourceRules`` and ``nonResourceRules`` has to be non-empty.

        :schema: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects#resourceRules
        '''
        result = self._values.get("resource_rules")
        return typing.cast(typing.Optional[typing.List["ResourcePolicyRuleV1Beta1"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PolicyRulesWithSubjectsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PolicyRulesWithSubjectsV1Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "subjects": "subjects",
        "non_resource_rules": "nonResourceRules",
        "resource_rules": "resourceRules",
    },
)
class PolicyRulesWithSubjectsV1Beta2:
    def __init__(
        self,
        *,
        subjects: typing.Sequence[typing.Union["SubjectV1Beta2", typing.Dict[str, typing.Any]]],
        non_resource_rules: typing.Optional[typing.Sequence[typing.Union[NonResourcePolicyRuleV1Beta2, typing.Dict[str, typing.Any]]]] = None,
        resource_rules: typing.Optional[typing.Sequence[typing.Union["ResourcePolicyRuleV1Beta2", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''PolicyRulesWithSubjects prescribes a test that applies to a request to an apiserver.

        The test considers the subject making the request, the verb being requested, and the resource to be acted upon. This PolicyRulesWithSubjects matches a request if and only if both (a) at least one member of subjects matches the request and (b) at least one member of resourceRules or nonResourceRules matches the request.

        :param subjects: subjects is the list of normal user, serviceaccount, or group that this rule cares about. There must be at least one member in this slice. A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. Required.
        :param non_resource_rules: ``nonResourceRules`` is a list of NonResourcePolicyRules that identify matching requests according to their verb and the target non-resource URL.
        :param resource_rules: ``resourceRules`` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the target resource. At least one of ``resourceRules`` and ``nonResourceRules`` has to be non-empty.

        :schema: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects
        '''
        if __debug__:
            def stub(
                *,
                subjects: typing.Sequence[typing.Union[SubjectV1Beta2, typing.Dict[str, typing.Any]]],
                non_resource_rules: typing.Optional[typing.Sequence[typing.Union[NonResourcePolicyRuleV1Beta2, typing.Dict[str, typing.Any]]]] = None,
                resource_rules: typing.Optional[typing.Sequence[typing.Union[ResourcePolicyRuleV1Beta2, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument subjects", value=subjects, expected_type=type_hints["subjects"])
            check_type(argname="argument non_resource_rules", value=non_resource_rules, expected_type=type_hints["non_resource_rules"])
            check_type(argname="argument resource_rules", value=resource_rules, expected_type=type_hints["resource_rules"])
        self._values: typing.Dict[str, typing.Any] = {
            "subjects": subjects,
        }
        if non_resource_rules is not None:
            self._values["non_resource_rules"] = non_resource_rules
        if resource_rules is not None:
            self._values["resource_rules"] = resource_rules

    @builtins.property
    def subjects(self) -> typing.List["SubjectV1Beta2"]:
        '''subjects is the list of normal user, serviceaccount, or group that this rule cares about.

        There must be at least one member in this slice. A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects#subjects
        '''
        result = self._values.get("subjects")
        assert result is not None, "Required property 'subjects' is missing"
        return typing.cast(typing.List["SubjectV1Beta2"], result)

    @builtins.property
    def non_resource_rules(
        self,
    ) -> typing.Optional[typing.List[NonResourcePolicyRuleV1Beta2]]:
        '''``nonResourceRules`` is a list of NonResourcePolicyRules that identify matching requests according to their verb and the target non-resource URL.

        :schema: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects#nonResourceRules
        '''
        result = self._values.get("non_resource_rules")
        return typing.cast(typing.Optional[typing.List[NonResourcePolicyRuleV1Beta2]], result)

    @builtins.property
    def resource_rules(
        self,
    ) -> typing.Optional[typing.List["ResourcePolicyRuleV1Beta2"]]:
        '''``resourceRules`` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the target resource.

        At least one of ``resourceRules`` and ``nonResourceRules`` has to be non-empty.

        :schema: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects#resourceRules
        '''
        result = self._values.get("resource_rules")
        return typing.cast(typing.Optional[typing.List["ResourcePolicyRuleV1Beta2"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PolicyRulesWithSubjectsV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PortworxVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "volume_id": "volumeId",
        "fs_type": "fsType",
        "read_only": "readOnly",
    },
)
class PortworxVolumeSource:
    def __init__(
        self,
        *,
        volume_id: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''PortworxVolumeSource represents a Portworx volume resource.

        :param volume_id: VolumeID uniquely identifies a Portworx volume.
        :param fs_type: FSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.PortworxVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                volume_id: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument volume_id", value=volume_id, expected_type=type_hints["volume_id"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
        self._values: typing.Dict[str, typing.Any] = {
            "volume_id": volume_id,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if read_only is not None:
            self._values["read_only"] = read_only

    @builtins.property
    def volume_id(self) -> builtins.str:
        '''VolumeID uniquely identifies a Portworx volume.

        :schema: io.k8s.api.core.v1.PortworxVolumeSource#volumeID
        '''
        result = self._values.get("volume_id")
        assert result is not None, "Required property 'volume_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''FSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system.

        Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.PortworxVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.PortworxVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PortworxVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Preconditions",
    jsii_struct_bases=[],
    name_mapping={"resource_version": "resourceVersion", "uid": "uid"},
)
class Preconditions:
    def __init__(
        self,
        *,
        resource_version: typing.Optional[builtins.str] = None,
        uid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.

        :param resource_version: Specifies the target ResourceVersion.
        :param uid: Specifies the target UID.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions
        '''
        if __debug__:
            def stub(
                *,
                resource_version: typing.Optional[builtins.str] = None,
                uid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument resource_version", value=resource_version, expected_type=type_hints["resource_version"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
        self._values: typing.Dict[str, typing.Any] = {}
        if resource_version is not None:
            self._values["resource_version"] = resource_version
        if uid is not None:
            self._values["uid"] = uid

    @builtins.property
    def resource_version(self) -> typing.Optional[builtins.str]:
        '''Specifies the target ResourceVersion.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions#resourceVersion
        '''
        result = self._values.get("resource_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''Specifies the target UID.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Preconditions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PreferredSchedulingTerm",
    jsii_struct_bases=[],
    name_mapping={"preference": "preference", "weight": "weight"},
)
class PreferredSchedulingTerm:
    def __init__(
        self,
        *,
        preference: typing.Union[NodeSelectorTerm, typing.Dict[str, typing.Any]],
        weight: jsii.Number,
    ) -> None:
        '''An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).

        :param preference: A node selector term, associated with the corresponding weight.
        :param weight: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.

        :schema: io.k8s.api.core.v1.PreferredSchedulingTerm
        '''
        if isinstance(preference, dict):
            preference = NodeSelectorTerm(**preference)
        if __debug__:
            def stub(
                *,
                preference: typing.Union[NodeSelectorTerm, typing.Dict[str, typing.Any]],
                weight: jsii.Number,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument preference", value=preference, expected_type=type_hints["preference"])
            check_type(argname="argument weight", value=weight, expected_type=type_hints["weight"])
        self._values: typing.Dict[str, typing.Any] = {
            "preference": preference,
            "weight": weight,
        }

    @builtins.property
    def preference(self) -> NodeSelectorTerm:
        '''A node selector term, associated with the corresponding weight.

        :schema: io.k8s.api.core.v1.PreferredSchedulingTerm#preference
        '''
        result = self._values.get("preference")
        assert result is not None, "Required property 'preference' is missing"
        return typing.cast(NodeSelectorTerm, result)

    @builtins.property
    def weight(self) -> jsii.Number:
        '''Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.

        :schema: io.k8s.api.core.v1.PreferredSchedulingTerm#weight
        '''
        result = self._values.get("weight")
        assert result is not None, "Required property 'weight' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PreferredSchedulingTerm(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PriorityLevelConfigurationReferenceV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class PriorityLevelConfigurationReferenceV1Beta1:
    def __init__(self, *, name: builtins.str) -> None:
        '''PriorityLevelConfigurationReference contains information that points to the "request-priority" being used.

        :param name: ``name`` is the name of the priority level configuration being referenced Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationReference
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the name of the priority level configuration being referenced Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PriorityLevelConfigurationReferenceV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PriorityLevelConfigurationReferenceV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class PriorityLevelConfigurationReferenceV1Beta2:
    def __init__(self, *, name: builtins.str) -> None:
        '''PriorityLevelConfigurationReference contains information that points to the "request-priority" being used.

        :param name: ``name`` is the name of the priority level configuration being referenced Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationReference
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the name of the priority level configuration being referenced Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PriorityLevelConfigurationReferenceV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PriorityLevelConfigurationSpecV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "limited": "limited"},
)
class PriorityLevelConfigurationSpecV1Beta1:
    def __init__(
        self,
        *,
        type: builtins.str,
        limited: typing.Optional[typing.Union[LimitedPriorityLevelConfigurationV1Beta1, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityLevelConfigurationSpec specifies the configuration of a priority level.

        :param type: ``type`` indicates whether this priority level is subject to limitation on request execution. A value of ``"Exempt"`` means that requests of this priority level are not subject to a limit (and thus are never queued) and do not detract from the capacity made available to other priority levels. A value of ``"Limited"`` means that (a) requests of this priority level *are* subject to limits and (b) some of the server's limited capacity is made available exclusively to this priority level. Required.
        :param limited: ``limited`` specifies how requests are handled for a Limited priority level. This field must be non-empty if and only if ``type`` is ``"Limited"``.

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec
        '''
        if isinstance(limited, dict):
            limited = LimitedPriorityLevelConfigurationV1Beta1(**limited)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                limited: typing.Optional[typing.Union[LimitedPriorityLevelConfigurationV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument limited", value=limited, expected_type=type_hints["limited"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if limited is not None:
            self._values["limited"] = limited

    @builtins.property
    def type(self) -> builtins.str:
        '''``type`` indicates whether this priority level is subject to limitation on request execution.

        A value of ``"Exempt"`` means that requests of this priority level are not subject to a limit (and thus are never queued) and do not detract from the capacity made available to other priority levels.  A value of ``"Limited"`` means that (a) requests of this priority level *are* subject to limits and (b) some of the server's limited capacity is made available exclusively to this priority level. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def limited(self) -> typing.Optional[LimitedPriorityLevelConfigurationV1Beta1]:
        '''``limited`` specifies how requests are handled for a Limited priority level.

        This field must be non-empty if and only if ``type`` is ``"Limited"``.

        :schema: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec#limited
        '''
        result = self._values.get("limited")
        return typing.cast(typing.Optional[LimitedPriorityLevelConfigurationV1Beta1], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PriorityLevelConfigurationSpecV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.PriorityLevelConfigurationSpecV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "limited": "limited"},
)
class PriorityLevelConfigurationSpecV1Beta2:
    def __init__(
        self,
        *,
        type: builtins.str,
        limited: typing.Optional[typing.Union[LimitedPriorityLevelConfigurationV1Beta2, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''PriorityLevelConfigurationSpec specifies the configuration of a priority level.

        :param type: ``type`` indicates whether this priority level is subject to limitation on request execution. A value of ``"Exempt"`` means that requests of this priority level are not subject to a limit (and thus are never queued) and do not detract from the capacity made available to other priority levels. A value of ``"Limited"`` means that (a) requests of this priority level *are* subject to limits and (b) some of the server's limited capacity is made available exclusively to this priority level. Required.
        :param limited: ``limited`` specifies how requests are handled for a Limited priority level. This field must be non-empty if and only if ``type`` is ``"Limited"``.

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec
        '''
        if isinstance(limited, dict):
            limited = LimitedPriorityLevelConfigurationV1Beta2(**limited)
        if __debug__:
            def stub(
                *,
                type: builtins.str,
                limited: typing.Optional[typing.Union[LimitedPriorityLevelConfigurationV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument limited", value=limited, expected_type=type_hints["limited"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if limited is not None:
            self._values["limited"] = limited

    @builtins.property
    def type(self) -> builtins.str:
        '''``type`` indicates whether this priority level is subject to limitation on request execution.

        A value of ``"Exempt"`` means that requests of this priority level are not subject to a limit (and thus are never queued) and do not detract from the capacity made available to other priority levels.  A value of ``"Limited"`` means that (a) requests of this priority level *are* subject to limits and (b) some of the server's limited capacity is made available exclusively to this priority level. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def limited(self) -> typing.Optional[LimitedPriorityLevelConfigurationV1Beta2]:
        '''``limited`` specifies how requests are handled for a Limited priority level.

        This field must be non-empty if and only if ``type`` is ``"Limited"``.

        :schema: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec#limited
        '''
        result = self._values.get("limited")
        return typing.cast(typing.Optional[LimitedPriorityLevelConfigurationV1Beta2], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PriorityLevelConfigurationSpecV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Probe",
    jsii_struct_bases=[],
    name_mapping={
        "exec": "exec",
        "failure_threshold": "failureThreshold",
        "grpc": "grpc",
        "http_get": "httpGet",
        "initial_delay_seconds": "initialDelaySeconds",
        "period_seconds": "periodSeconds",
        "success_threshold": "successThreshold",
        "tcp_socket": "tcpSocket",
        "termination_grace_period_seconds": "terminationGracePeriodSeconds",
        "timeout_seconds": "timeoutSeconds",
    },
)
class Probe:
    def __init__(
        self,
        *,
        exec: typing.Optional[typing.Union[ExecAction, typing.Dict[str, typing.Any]]] = None,
        failure_threshold: typing.Optional[jsii.Number] = None,
        grpc: typing.Optional[typing.Union[GrpcAction, typing.Dict[str, typing.Any]]] = None,
        http_get: typing.Optional[typing.Union[HttpGetAction, typing.Dict[str, typing.Any]]] = None,
        initial_delay_seconds: typing.Optional[jsii.Number] = None,
        period_seconds: typing.Optional[jsii.Number] = None,
        success_threshold: typing.Optional[jsii.Number] = None,
        tcp_socket: typing.Optional[typing.Union["TcpSocketAction", typing.Dict[str, typing.Any]]] = None,
        termination_grace_period_seconds: typing.Optional[jsii.Number] = None,
        timeout_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.

        :param exec: Exec specifies the action to take.
        :param failure_threshold: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. Default: 3. Minimum value is 1.
        :param grpc: GRPC specifies an action involving a GRPC port. This is an alpha field and requires enabling GRPCContainerProbe feature gate.
        :param http_get: HTTPGet specifies the http request to perform.
        :param initial_delay_seconds: Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
        :param period_seconds: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. Default: 10 seconds. Minimum value is 1.
        :param success_threshold: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. Default: 1. Must be 1 for liveness and startup. Minimum value is 1.
        :param tcp_socket: TCPSocket specifies an action involving a TCP port.
        :param termination_grace_period_seconds: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.
        :param timeout_seconds: Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes Default: 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :schema: io.k8s.api.core.v1.Probe
        '''
        if isinstance(exec, dict):
            exec = ExecAction(**exec)
        if isinstance(grpc, dict):
            grpc = GrpcAction(**grpc)
        if isinstance(http_get, dict):
            http_get = HttpGetAction(**http_get)
        if isinstance(tcp_socket, dict):
            tcp_socket = TcpSocketAction(**tcp_socket)
        if __debug__:
            def stub(
                *,
                exec: typing.Optional[typing.Union[ExecAction, typing.Dict[str, typing.Any]]] = None,
                failure_threshold: typing.Optional[jsii.Number] = None,
                grpc: typing.Optional[typing.Union[GrpcAction, typing.Dict[str, typing.Any]]] = None,
                http_get: typing.Optional[typing.Union[HttpGetAction, typing.Dict[str, typing.Any]]] = None,
                initial_delay_seconds: typing.Optional[jsii.Number] = None,
                period_seconds: typing.Optional[jsii.Number] = None,
                success_threshold: typing.Optional[jsii.Number] = None,
                tcp_socket: typing.Optional[typing.Union[TcpSocketAction, typing.Dict[str, typing.Any]]] = None,
                termination_grace_period_seconds: typing.Optional[jsii.Number] = None,
                timeout_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument exec", value=exec, expected_type=type_hints["exec"])
            check_type(argname="argument failure_threshold", value=failure_threshold, expected_type=type_hints["failure_threshold"])
            check_type(argname="argument grpc", value=grpc, expected_type=type_hints["grpc"])
            check_type(argname="argument http_get", value=http_get, expected_type=type_hints["http_get"])
            check_type(argname="argument initial_delay_seconds", value=initial_delay_seconds, expected_type=type_hints["initial_delay_seconds"])
            check_type(argname="argument period_seconds", value=period_seconds, expected_type=type_hints["period_seconds"])
            check_type(argname="argument success_threshold", value=success_threshold, expected_type=type_hints["success_threshold"])
            check_type(argname="argument tcp_socket", value=tcp_socket, expected_type=type_hints["tcp_socket"])
            check_type(argname="argument termination_grace_period_seconds", value=termination_grace_period_seconds, expected_type=type_hints["termination_grace_period_seconds"])
            check_type(argname="argument timeout_seconds", value=timeout_seconds, expected_type=type_hints["timeout_seconds"])
        self._values: typing.Dict[str, typing.Any] = {}
        if exec is not None:
            self._values["exec"] = exec
        if failure_threshold is not None:
            self._values["failure_threshold"] = failure_threshold
        if grpc is not None:
            self._values["grpc"] = grpc
        if http_get is not None:
            self._values["http_get"] = http_get
        if initial_delay_seconds is not None:
            self._values["initial_delay_seconds"] = initial_delay_seconds
        if period_seconds is not None:
            self._values["period_seconds"] = period_seconds
        if success_threshold is not None:
            self._values["success_threshold"] = success_threshold
        if tcp_socket is not None:
            self._values["tcp_socket"] = tcp_socket
        if termination_grace_period_seconds is not None:
            self._values["termination_grace_period_seconds"] = termination_grace_period_seconds
        if timeout_seconds is not None:
            self._values["timeout_seconds"] = timeout_seconds

    @builtins.property
    def exec(self) -> typing.Optional[ExecAction]:
        '''Exec specifies the action to take.

        :schema: io.k8s.api.core.v1.Probe#exec
        '''
        result = self._values.get("exec")
        return typing.cast(typing.Optional[ExecAction], result)

    @builtins.property
    def failure_threshold(self) -> typing.Optional[jsii.Number]:
        '''Minimum consecutive failures for the probe to be considered failed after having succeeded.

        Defaults to 3. Minimum value is 1.

        :default: 3. Minimum value is 1.

        :schema: io.k8s.api.core.v1.Probe#failureThreshold
        '''
        result = self._values.get("failure_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def grpc(self) -> typing.Optional[GrpcAction]:
        '''GRPC specifies an action involving a GRPC port.

        This is an alpha field and requires enabling GRPCContainerProbe feature gate.

        :schema: io.k8s.api.core.v1.Probe#grpc
        '''
        result = self._values.get("grpc")
        return typing.cast(typing.Optional[GrpcAction], result)

    @builtins.property
    def http_get(self) -> typing.Optional[HttpGetAction]:
        '''HTTPGet specifies the http request to perform.

        :schema: io.k8s.api.core.v1.Probe#httpGet
        '''
        result = self._values.get("http_get")
        return typing.cast(typing.Optional[HttpGetAction], result)

    @builtins.property
    def initial_delay_seconds(self) -> typing.Optional[jsii.Number]:
        '''Number of seconds after the container has started before liveness probes are initiated.

        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :schema: io.k8s.api.core.v1.Probe#initialDelaySeconds
        '''
        result = self._values.get("initial_delay_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def period_seconds(self) -> typing.Optional[jsii.Number]:
        '''How often (in seconds) to perform the probe.

        Default to 10 seconds. Minimum value is 1.

        :default: 10 seconds. Minimum value is 1.

        :schema: io.k8s.api.core.v1.Probe#periodSeconds
        '''
        result = self._values.get("period_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def success_threshold(self) -> typing.Optional[jsii.Number]:
        '''Minimum consecutive successes for the probe to be considered successful after having failed.

        Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.

        :default: 1. Must be 1 for liveness and startup. Minimum value is 1.

        :schema: io.k8s.api.core.v1.Probe#successThreshold
        '''
        result = self._values.get("success_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tcp_socket(self) -> typing.Optional["TcpSocketAction"]:
        '''TCPSocket specifies an action involving a TCP port.

        :schema: io.k8s.api.core.v1.Probe#tcpSocket
        '''
        result = self._values.get("tcp_socket")
        return typing.cast(typing.Optional["TcpSocketAction"], result)

    @builtins.property
    def termination_grace_period_seconds(self) -> typing.Optional[jsii.Number]:
        '''Optional duration in seconds the pod needs to terminate gracefully upon probe failure.

        The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.

        :schema: io.k8s.api.core.v1.Probe#terminationGracePeriodSeconds
        '''
        result = self._values.get("termination_grace_period_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def timeout_seconds(self) -> typing.Optional[jsii.Number]:
        '''Number of seconds after which the probe times out.

        Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :default: 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

        :schema: io.k8s.api.core.v1.Probe#timeoutSeconds
        '''
        result = self._values.get("timeout_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Probe(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ProjectedVolumeSource",
    jsii_struct_bases=[],
    name_mapping={"default_mode": "defaultMode", "sources": "sources"},
)
class ProjectedVolumeSource:
    def __init__(
        self,
        *,
        default_mode: typing.Optional[jsii.Number] = None,
        sources: typing.Optional[typing.Sequence[typing.Union["VolumeProjection", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Represents a projected volume source.

        :param default_mode: Mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.
        :param sources: list of volume projections.

        :schema: io.k8s.api.core.v1.ProjectedVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                default_mode: typing.Optional[jsii.Number] = None,
                sources: typing.Optional[typing.Sequence[typing.Union[VolumeProjection, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument default_mode", value=default_mode, expected_type=type_hints["default_mode"])
            check_type(argname="argument sources", value=sources, expected_type=type_hints["sources"])
        self._values: typing.Dict[str, typing.Any] = {}
        if default_mode is not None:
            self._values["default_mode"] = default_mode
        if sources is not None:
            self._values["sources"] = sources

    @builtins.property
    def default_mode(self) -> typing.Optional[jsii.Number]:
        '''Mode bits used to set permissions on created files by default.

        Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.ProjectedVolumeSource#defaultMode
        '''
        result = self._values.get("default_mode")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def sources(self) -> typing.Optional[typing.List["VolumeProjection"]]:
        '''list of volume projections.

        :schema: io.k8s.api.core.v1.ProjectedVolumeSource#sources
        '''
        result = self._values.get("sources")
        return typing.cast(typing.Optional[typing.List["VolumeProjection"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ProjectedVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class Quantity(metaclass=jsii.JSIIMeta, jsii_type="cdk8s-plus-23.k8s.Quantity"):
    '''
    :schema: io.k8s.apimachinery.pkg.api.resource.Quantity
    '''

    @jsii.member(jsii_name="fromNumber")
    @builtins.classmethod
    def from_number(cls, value: jsii.Number) -> "Quantity":
        '''
        :param value: -
        '''
        if __debug__:
            def stub(value: jsii.Number) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        return typing.cast("Quantity", jsii.sinvoke(cls, "fromNumber", [value]))

    @jsii.member(jsii_name="fromString")
    @builtins.classmethod
    def from_string(cls, value: builtins.str) -> "Quantity":
        '''
        :param value: -
        '''
        if __debug__:
            def stub(value: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        return typing.cast("Quantity", jsii.sinvoke(cls, "fromString", [value]))

    @builtins.property
    @jsii.member(jsii_name="value")
    def value(self) -> typing.Any:
        return typing.cast(typing.Any, jsii.get(self, "value"))


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.QueuingConfigurationV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "hand_size": "handSize",
        "queue_length_limit": "queueLengthLimit",
        "queues": "queues",
    },
)
class QueuingConfigurationV1Beta1:
    def __init__(
        self,
        *,
        hand_size: typing.Optional[jsii.Number] = None,
        queue_length_limit: typing.Optional[jsii.Number] = None,
        queues: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''QueuingConfiguration holds the configuration parameters for queuing.

        :param hand_size: ``handSize`` is a small positive number that configures the shuffle sharding of requests into queues. When enqueuing a request at this priority level the request's flow identifier (a string pair) is hashed and the hash value is used to shuffle the list of queues and deal a hand of the size specified here. The request is put into one of the shortest queues in that hand. ``handSize`` must be no larger than ``queues``, and should be significantly smaller (so that a few heavy flows do not saturate most of the queues). See the user-facing documentation for more extensive guidance on setting this field. This field has a default value of 8.
        :param queue_length_limit: ``queueLengthLimit`` is the maximum number of requests allowed to be waiting in a given queue of this priority level at a time; excess requests are rejected. This value must be positive. If not specified, it will be defaulted to 50.
        :param queues: ``queues`` is the number of queues for this priority level. The queues exist independently at each apiserver. The value must be positive. Setting it to 1 effectively precludes shufflesharding and thus makes the distinguisher method of associated flow schemas irrelevant. This field has a default value of 64.

        :schema: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration
        '''
        if __debug__:
            def stub(
                *,
                hand_size: typing.Optional[jsii.Number] = None,
                queue_length_limit: typing.Optional[jsii.Number] = None,
                queues: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument hand_size", value=hand_size, expected_type=type_hints["hand_size"])
            check_type(argname="argument queue_length_limit", value=queue_length_limit, expected_type=type_hints["queue_length_limit"])
            check_type(argname="argument queues", value=queues, expected_type=type_hints["queues"])
        self._values: typing.Dict[str, typing.Any] = {}
        if hand_size is not None:
            self._values["hand_size"] = hand_size
        if queue_length_limit is not None:
            self._values["queue_length_limit"] = queue_length_limit
        if queues is not None:
            self._values["queues"] = queues

    @builtins.property
    def hand_size(self) -> typing.Optional[jsii.Number]:
        '''``handSize`` is a small positive number that configures the shuffle sharding of requests into queues.

        When enqueuing a request at this priority level the request's flow identifier (a string pair) is hashed and the hash value is used to shuffle the list of queues and deal a hand of the size specified here.  The request is put into one of the shortest queues in that hand. ``handSize`` must be no larger than ``queues``, and should be significantly smaller (so that a few heavy flows do not saturate most of the queues).  See the user-facing documentation for more extensive guidance on setting this field.  This field has a default value of 8.

        :schema: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration#handSize
        '''
        result = self._values.get("hand_size")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def queue_length_limit(self) -> typing.Optional[jsii.Number]:
        '''``queueLengthLimit`` is the maximum number of requests allowed to be waiting in a given queue of this priority level at a time;

        excess requests are rejected.  This value must be positive.  If not specified, it will be defaulted to 50.

        :schema: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration#queueLengthLimit
        '''
        result = self._values.get("queue_length_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def queues(self) -> typing.Optional[jsii.Number]:
        '''``queues`` is the number of queues for this priority level.

        The queues exist independently at each apiserver. The value must be positive.  Setting it to 1 effectively precludes shufflesharding and thus makes the distinguisher method of associated flow schemas irrelevant.  This field has a default value of 64.

        :schema: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration#queues
        '''
        result = self._values.get("queues")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "QueuingConfigurationV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.QueuingConfigurationV1Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "hand_size": "handSize",
        "queue_length_limit": "queueLengthLimit",
        "queues": "queues",
    },
)
class QueuingConfigurationV1Beta2:
    def __init__(
        self,
        *,
        hand_size: typing.Optional[jsii.Number] = None,
        queue_length_limit: typing.Optional[jsii.Number] = None,
        queues: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''QueuingConfiguration holds the configuration parameters for queuing.

        :param hand_size: ``handSize`` is a small positive number that configures the shuffle sharding of requests into queues. When enqueuing a request at this priority level the request's flow identifier (a string pair) is hashed and the hash value is used to shuffle the list of queues and deal a hand of the size specified here. The request is put into one of the shortest queues in that hand. ``handSize`` must be no larger than ``queues``, and should be significantly smaller (so that a few heavy flows do not saturate most of the queues). See the user-facing documentation for more extensive guidance on setting this field. This field has a default value of 8.
        :param queue_length_limit: ``queueLengthLimit`` is the maximum number of requests allowed to be waiting in a given queue of this priority level at a time; excess requests are rejected. This value must be positive. If not specified, it will be defaulted to 50.
        :param queues: ``queues`` is the number of queues for this priority level. The queues exist independently at each apiserver. The value must be positive. Setting it to 1 effectively precludes shufflesharding and thus makes the distinguisher method of associated flow schemas irrelevant. This field has a default value of 64.

        :schema: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration
        '''
        if __debug__:
            def stub(
                *,
                hand_size: typing.Optional[jsii.Number] = None,
                queue_length_limit: typing.Optional[jsii.Number] = None,
                queues: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument hand_size", value=hand_size, expected_type=type_hints["hand_size"])
            check_type(argname="argument queue_length_limit", value=queue_length_limit, expected_type=type_hints["queue_length_limit"])
            check_type(argname="argument queues", value=queues, expected_type=type_hints["queues"])
        self._values: typing.Dict[str, typing.Any] = {}
        if hand_size is not None:
            self._values["hand_size"] = hand_size
        if queue_length_limit is not None:
            self._values["queue_length_limit"] = queue_length_limit
        if queues is not None:
            self._values["queues"] = queues

    @builtins.property
    def hand_size(self) -> typing.Optional[jsii.Number]:
        '''``handSize`` is a small positive number that configures the shuffle sharding of requests into queues.

        When enqueuing a request at this priority level the request's flow identifier (a string pair) is hashed and the hash value is used to shuffle the list of queues and deal a hand of the size specified here.  The request is put into one of the shortest queues in that hand. ``handSize`` must be no larger than ``queues``, and should be significantly smaller (so that a few heavy flows do not saturate most of the queues).  See the user-facing documentation for more extensive guidance on setting this field.  This field has a default value of 8.

        :schema: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration#handSize
        '''
        result = self._values.get("hand_size")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def queue_length_limit(self) -> typing.Optional[jsii.Number]:
        '''``queueLengthLimit`` is the maximum number of requests allowed to be waiting in a given queue of this priority level at a time;

        excess requests are rejected.  This value must be positive.  If not specified, it will be defaulted to 50.

        :schema: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration#queueLengthLimit
        '''
        result = self._values.get("queue_length_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def queues(self) -> typing.Optional[jsii.Number]:
        '''``queues`` is the number of queues for this priority level.

        The queues exist independently at each apiserver. The value must be positive.  Setting it to 1 effectively precludes shufflesharding and thus makes the distinguisher method of associated flow schemas irrelevant.  This field has a default value of 64.

        :schema: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration#queues
        '''
        result = self._values.get("queues")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "QueuingConfigurationV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.QuobyteVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "registry": "registry",
        "volume": "volume",
        "group": "group",
        "read_only": "readOnly",
        "tenant": "tenant",
        "user": "user",
    },
)
class QuobyteVolumeSource:
    def __init__(
        self,
        *,
        registry: builtins.str,
        volume: builtins.str,
        group: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        tenant: typing.Optional[builtins.str] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Quobyte mount that lasts the lifetime of a pod.

        Quobyte volumes do not support ownership management or SELinux relabeling.

        :param registry: Registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes.
        :param volume: Volume is a string that references an already created Quobyte volume by name.
        :param group: Group to map volume access to Default is no group. Default: no group
        :param read_only: ReadOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. Default: false.
        :param tenant: Tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin.
        :param user: User to map volume access to Defaults to serivceaccount user. Default: serivceaccount user

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                registry: builtins.str,
                volume: builtins.str,
                group: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                tenant: typing.Optional[builtins.str] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument registry", value=registry, expected_type=type_hints["registry"])
            check_type(argname="argument volume", value=volume, expected_type=type_hints["volume"])
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument tenant", value=tenant, expected_type=type_hints["tenant"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "registry": registry,
            "volume": volume,
        }
        if group is not None:
            self._values["group"] = group
        if read_only is not None:
            self._values["read_only"] = read_only
        if tenant is not None:
            self._values["tenant"] = tenant
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def registry(self) -> builtins.str:
        '''Registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes.

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource#registry
        '''
        result = self._values.get("registry")
        assert result is not None, "Required property 'registry' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def volume(self) -> builtins.str:
        '''Volume is a string that references an already created Quobyte volume by name.

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource#volume
        '''
        result = self._values.get("volume")
        assert result is not None, "Required property 'volume' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def group(self) -> typing.Optional[builtins.str]:
        '''Group to map volume access to Default is no group.

        :default: no group

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource#group
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the Quobyte volume to be mounted with read-only permissions.

        Defaults to false.

        :default: false.

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def tenant(self) -> typing.Optional[builtins.str]:
        '''Tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin.

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource#tenant
        '''
        result = self._values.get("tenant")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''User to map volume access to Defaults to serivceaccount user.

        :default: serivceaccount user

        :schema: io.k8s.api.core.v1.QuobyteVolumeSource#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "QuobyteVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RbdPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "image": "image",
        "monitors": "monitors",
        "fs_type": "fsType",
        "keyring": "keyring",
        "pool": "pool",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
        "user": "user",
    },
)
class RbdPersistentVolumeSource:
    def __init__(
        self,
        *,
        image: builtins.str,
        monitors: typing.Sequence[builtins.str],
        fs_type: typing.Optional[builtins.str] = None,
        keyring: typing.Optional[builtins.str] = None,
        pool: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union["SecretReference", typing.Dict[str, typing.Any]]] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Rados Block Device mount that lasts the lifetime of a pod.

        RBD volumes support ownership management and SELinux relabeling.

        :param image: The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param monitors: A collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param fs_type: Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
        :param keyring: Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param pool: The rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param read_only: ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param secret_ref: SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param user: The rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = SecretReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                image: builtins.str,
                monitors: typing.Sequence[builtins.str],
                fs_type: typing.Optional[builtins.str] = None,
                keyring: typing.Optional[builtins.str] = None,
                pool: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[SecretReference, typing.Dict[str, typing.Any]]] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument image", value=image, expected_type=type_hints["image"])
            check_type(argname="argument monitors", value=monitors, expected_type=type_hints["monitors"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument keyring", value=keyring, expected_type=type_hints["keyring"])
            check_type(argname="argument pool", value=pool, expected_type=type_hints["pool"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "image": image,
            "monitors": monitors,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if keyring is not None:
            self._values["keyring"] = keyring
        if pool is not None:
            self._values["pool"] = pool
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def image(self) -> builtins.str:
        '''The rados image name.

        More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#image
        '''
        result = self._values.get("image")
        assert result is not None, "Required property 'image' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def monitors(self) -> typing.List[builtins.str]:
        '''A collection of Ceph monitors.

        More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#monitors
        '''
        result = self._values.get("monitors")
        assert result is not None, "Required property 'monitors' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type of the volume that you want to mount.

        Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def keyring(self) -> typing.Optional[builtins.str]:
        '''Keyring is the path to key ring for RBDUser.

        Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#keyring
        '''
        result = self._values.get("keyring")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def pool(self) -> typing.Optional[builtins.str]:
        '''The rados pool name.

        Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#pool
        '''
        result = self._values.get("pool")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the ReadOnly setting in VolumeMounts.

        Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional["SecretReference"]:
        '''SecretRef is name of the authentication secret for RBDUser.

        If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional["SecretReference"], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''The rados user name.

        Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDPersistentVolumeSource#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RbdPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RbdVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "image": "image",
        "monitors": "monitors",
        "fs_type": "fsType",
        "keyring": "keyring",
        "pool": "pool",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
        "user": "user",
    },
)
class RbdVolumeSource:
    def __init__(
        self,
        *,
        image: builtins.str,
        monitors: typing.Sequence[builtins.str],
        fs_type: typing.Optional[builtins.str] = None,
        keyring: typing.Optional[builtins.str] = None,
        pool: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a Rados Block Device mount that lasts the lifetime of a pod.

        RBD volumes support ownership management and SELinux relabeling.

        :param image: The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param monitors: A collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param fs_type: Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
        :param keyring: Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param pool: The rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param read_only: ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param secret_ref: SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
        :param user: The rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it Default: admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                image: builtins.str,
                monitors: typing.Sequence[builtins.str],
                fs_type: typing.Optional[builtins.str] = None,
                keyring: typing.Optional[builtins.str] = None,
                pool: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument image", value=image, expected_type=type_hints["image"])
            check_type(argname="argument monitors", value=monitors, expected_type=type_hints["monitors"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument keyring", value=keyring, expected_type=type_hints["keyring"])
            check_type(argname="argument pool", value=pool, expected_type=type_hints["pool"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "image": image,
            "monitors": monitors,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if keyring is not None:
            self._values["keyring"] = keyring
        if pool is not None:
            self._values["pool"] = pool
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def image(self) -> builtins.str:
        '''The rados image name.

        More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#image
        '''
        result = self._values.get("image")
        assert result is not None, "Required property 'image' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def monitors(self) -> typing.List[builtins.str]:
        '''A collection of Ceph monitors.

        More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#monitors
        '''
        result = self._values.get("monitors")
        assert result is not None, "Required property 'monitors' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type of the volume that you want to mount.

        Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd

        :schema: io.k8s.api.core.v1.RBDVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def keyring(self) -> typing.Optional[builtins.str]:
        '''Keyring is the path to key ring for RBDUser.

        Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#keyring
        '''
        result = self._values.get("keyring")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def pool(self) -> typing.Optional[builtins.str]:
        '''The rados pool name.

        Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#pool
        '''
        result = self._values.get("pool")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''ReadOnly here will force the ReadOnly setting in VolumeMounts.

        Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional[LocalObjectReference]:
        '''SecretRef is name of the authentication secret for RBDUser.

        If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional[LocalObjectReference], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''The rados user name.

        Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :default: admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

        :schema: io.k8s.api.core.v1.RBDVolumeSource#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RbdVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ReplicaSetSpec",
    jsii_struct_bases=[],
    name_mapping={
        "selector": "selector",
        "min_ready_seconds": "minReadySeconds",
        "replicas": "replicas",
        "template": "template",
    },
)
class ReplicaSetSpec:
    def __init__(
        self,
        *,
        selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
        min_ready_seconds: typing.Optional[jsii.Number] = None,
        replicas: typing.Optional[jsii.Number] = None,
        template: typing.Optional[typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ReplicaSetSpec is the specification of a ReplicaSet.

        :param selector: Selector is a label query over pods that should match the replica count. Label keys and values that must match in order to be controlled by this replica set. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
        :param min_ready_seconds: Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) Default: 0 (pod will be considered available as soon as it is ready)
        :param replicas: Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller Default: 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
        :param template: Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template

        :schema: io.k8s.api.apps.v1.ReplicaSetSpec
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if __debug__:
            def stub(
                *,
                selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
                min_ready_seconds: typing.Optional[jsii.Number] = None,
                replicas: typing.Optional[jsii.Number] = None,
                template: typing.Optional[typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument min_ready_seconds", value=min_ready_seconds, expected_type=type_hints["min_ready_seconds"])
            check_type(argname="argument replicas", value=replicas, expected_type=type_hints["replicas"])
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
        self._values: typing.Dict[str, typing.Any] = {
            "selector": selector,
        }
        if min_ready_seconds is not None:
            self._values["min_ready_seconds"] = min_ready_seconds
        if replicas is not None:
            self._values["replicas"] = replicas
        if template is not None:
            self._values["template"] = template

    @builtins.property
    def selector(self) -> LabelSelector:
        '''Selector is a label query over pods that should match the replica count.

        Label keys and values that must match in order to be controlled by this replica set. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

        :schema: io.k8s.api.apps.v1.ReplicaSetSpec#selector
        '''
        result = self._values.get("selector")
        assert result is not None, "Required property 'selector' is missing"
        return typing.cast(LabelSelector, result)

    @builtins.property
    def min_ready_seconds(self) -> typing.Optional[jsii.Number]:
        '''Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available.

        Defaults to 0 (pod will be considered available as soon as it is ready)

        :default: 0 (pod will be considered available as soon as it is ready)

        :schema: io.k8s.api.apps.v1.ReplicaSetSpec#minReadySeconds
        '''
        result = self._values.get("min_ready_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def replicas(self) -> typing.Optional[jsii.Number]:
        '''Replicas is the number of desired replicas.

        This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller

        :default: 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller

        :schema: io.k8s.api.apps.v1.ReplicaSetSpec#replicas
        '''
        result = self._values.get("replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def template(self) -> typing.Optional[PodTemplateSpec]:
        '''Template is the object that describes the pod that will be created if insufficient replicas are detected.

        More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template

        :schema: io.k8s.api.apps.v1.ReplicaSetSpec#template
        '''
        result = self._values.get("template")
        return typing.cast(typing.Optional[PodTemplateSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ReplicaSetSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ReplicationControllerSpec",
    jsii_struct_bases=[],
    name_mapping={
        "min_ready_seconds": "minReadySeconds",
        "replicas": "replicas",
        "selector": "selector",
        "template": "template",
    },
)
class ReplicationControllerSpec:
    def __init__(
        self,
        *,
        min_ready_seconds: typing.Optional[jsii.Number] = None,
        replicas: typing.Optional[jsii.Number] = None,
        selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        template: typing.Optional[typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ReplicationControllerSpec is the specification of a replication controller.

        :param min_ready_seconds: Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) Default: 0 (pod will be considered available as soon as it is ready)
        :param replicas: Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller Default: 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller
        :param selector: Selector is a label query over pods that should match the Replicas count. If Selector is empty, it is defaulted to the labels present on the Pod template. Label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
        :param template: Template is the object that describes the pod that will be created if insufficient replicas are detected. This takes precedence over a TemplateRef. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template

        :schema: io.k8s.api.core.v1.ReplicationControllerSpec
        '''
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if __debug__:
            def stub(
                *,
                min_ready_seconds: typing.Optional[jsii.Number] = None,
                replicas: typing.Optional[jsii.Number] = None,
                selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                template: typing.Optional[typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument min_ready_seconds", value=min_ready_seconds, expected_type=type_hints["min_ready_seconds"])
            check_type(argname="argument replicas", value=replicas, expected_type=type_hints["replicas"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
        self._values: typing.Dict[str, typing.Any] = {}
        if min_ready_seconds is not None:
            self._values["min_ready_seconds"] = min_ready_seconds
        if replicas is not None:
            self._values["replicas"] = replicas
        if selector is not None:
            self._values["selector"] = selector
        if template is not None:
            self._values["template"] = template

    @builtins.property
    def min_ready_seconds(self) -> typing.Optional[jsii.Number]:
        '''Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available.

        Defaults to 0 (pod will be considered available as soon as it is ready)

        :default: 0 (pod will be considered available as soon as it is ready)

        :schema: io.k8s.api.core.v1.ReplicationControllerSpec#minReadySeconds
        '''
        result = self._values.get("min_ready_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def replicas(self) -> typing.Optional[jsii.Number]:
        '''Replicas is the number of desired replicas.

        This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller

        :default: 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller

        :schema: io.k8s.api.core.v1.ReplicationControllerSpec#replicas
        '''
        result = self._values.get("replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def selector(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Selector is a label query over pods that should match the Replicas count.

        If Selector is empty, it is defaulted to the labels present on the Pod template. Label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

        :schema: io.k8s.api.core.v1.ReplicationControllerSpec#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def template(self) -> typing.Optional[PodTemplateSpec]:
        '''Template is the object that describes the pod that will be created if insufficient replicas are detected.

        This takes precedence over a TemplateRef. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template

        :schema: io.k8s.api.core.v1.ReplicationControllerSpec#template
        '''
        result = self._values.get("template")
        return typing.cast(typing.Optional[PodTemplateSpec], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ReplicationControllerSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "group": "group",
        "name": "name",
        "namespace": "namespace",
        "resource": "resource",
        "subresource": "subresource",
        "verb": "verb",
        "version": "version",
    },
)
class ResourceAttributes:
    def __init__(
        self,
        *,
        group: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        namespace: typing.Optional[builtins.str] = None,
        resource: typing.Optional[builtins.str] = None,
        subresource: typing.Optional[builtins.str] = None,
        verb: typing.Optional[builtins.str] = None,
        version: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface.

        :param group: Group is the API Group of the Resource. "*" means all.
        :param name: Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all.
        :param namespace: Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces "" (empty) is defaulted for LocalSubjectAccessReviews "" (empty) is empty for cluster-scoped resources "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview
        :param resource: Resource is one of the existing resource types. "*" means all.
        :param subresource: Subresource is one of the existing resource types. "" means none.
        :param verb: Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.
        :param version: Version is the API Version of the Resource. "*" means all.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes
        '''
        if __debug__:
            def stub(
                *,
                group: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                namespace: typing.Optional[builtins.str] = None,
                resource: typing.Optional[builtins.str] = None,
                subresource: typing.Optional[builtins.str] = None,
                verb: typing.Optional[builtins.str] = None,
                version: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
            check_type(argname="argument resource", value=resource, expected_type=type_hints["resource"])
            check_type(argname="argument subresource", value=subresource, expected_type=type_hints["subresource"])
            check_type(argname="argument verb", value=verb, expected_type=type_hints["verb"])
            check_type(argname="argument version", value=version, expected_type=type_hints["version"])
        self._values: typing.Dict[str, typing.Any] = {}
        if group is not None:
            self._values["group"] = group
        if name is not None:
            self._values["name"] = name
        if namespace is not None:
            self._values["namespace"] = namespace
        if resource is not None:
            self._values["resource"] = resource
        if subresource is not None:
            self._values["subresource"] = subresource
        if verb is not None:
            self._values["verb"] = verb
        if version is not None:
            self._values["version"] = version

    @builtins.property
    def group(self) -> typing.Optional[builtins.str]:
        '''Group is the API Group of the Resource.

        "*" means all.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#group
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name is the name of the resource being requested for a "get" or deleted for a "delete".

        "" (empty) means all.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace is the namespace of the action being requested.

        Currently, there is no distinction between no namespace and all namespaces "" (empty) is defaulted for LocalSubjectAccessReviews "" (empty) is empty for cluster-scoped resources "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def resource(self) -> typing.Optional[builtins.str]:
        '''Resource is one of the existing resource types.

        "*" means all.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#resource
        '''
        result = self._values.get("resource")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subresource(self) -> typing.Optional[builtins.str]:
        '''Subresource is one of the existing resource types.

        "" means none.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#subresource
        '''
        result = self._values.get("subresource")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def verb(self) -> typing.Optional[builtins.str]:
        '''Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy.

        "*" means all.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#verb
        '''
        result = self._values.get("verb")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def version(self) -> typing.Optional[builtins.str]:
        '''Version is the API Version of the Resource.

        "*" means all.

        :schema: io.k8s.api.authorization.v1.ResourceAttributes#version
        '''
        result = self._values.get("version")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceFieldSelector",
    jsii_struct_bases=[],
    name_mapping={
        "resource": "resource",
        "container_name": "containerName",
        "divisor": "divisor",
    },
)
class ResourceFieldSelector:
    def __init__(
        self,
        *,
        resource: builtins.str,
        container_name: typing.Optional[builtins.str] = None,
        divisor: typing.Optional[Quantity] = None,
    ) -> None:
        '''ResourceFieldSelector represents container resources (cpu, memory) and their output format.

        :param resource: Required: resource to select.
        :param container_name: Container name: required for volumes, optional for env vars.
        :param divisor: Specifies the output format of the exposed resources, defaults to "1".

        :schema: io.k8s.api.core.v1.ResourceFieldSelector
        '''
        if __debug__:
            def stub(
                *,
                resource: builtins.str,
                container_name: typing.Optional[builtins.str] = None,
                divisor: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument resource", value=resource, expected_type=type_hints["resource"])
            check_type(argname="argument container_name", value=container_name, expected_type=type_hints["container_name"])
            check_type(argname="argument divisor", value=divisor, expected_type=type_hints["divisor"])
        self._values: typing.Dict[str, typing.Any] = {
            "resource": resource,
        }
        if container_name is not None:
            self._values["container_name"] = container_name
        if divisor is not None:
            self._values["divisor"] = divisor

    @builtins.property
    def resource(self) -> builtins.str:
        '''Required: resource to select.

        :schema: io.k8s.api.core.v1.ResourceFieldSelector#resource
        '''
        result = self._values.get("resource")
        assert result is not None, "Required property 'resource' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def container_name(self) -> typing.Optional[builtins.str]:
        '''Container name: required for volumes, optional for env vars.

        :schema: io.k8s.api.core.v1.ResourceFieldSelector#containerName
        '''
        result = self._values.get("container_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def divisor(self) -> typing.Optional[Quantity]:
        '''Specifies the output format of the exposed resources, defaults to "1".

        :schema: io.k8s.api.core.v1.ResourceFieldSelector#divisor
        '''
        result = self._values.get("divisor")
        return typing.cast(typing.Optional[Quantity], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceFieldSelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceMetricSourceV2",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "target": "target"},
)
class ResourceMetricSourceV2:
    def __init__(
        self,
        *,
        name: builtins.str,
        target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
    ) -> None:
        '''ResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory).  The values will be averaged together before being compared to the target.  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.  Only one "target" type should be set.

        :param name: name is the name of the resource in question.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ResourceMetricSource
        '''
        if isinstance(target, dict):
            target = MetricTargetV2(**target)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                target: typing.Union[MetricTargetV2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "target": target,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the resource in question.

        :schema: io.k8s.api.autoscaling.v2.ResourceMetricSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target(self) -> MetricTargetV2:
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2.ResourceMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(MetricTargetV2, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceMetricSourceV2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceMetricSourceV2Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "target_average_utilization": "targetAverageUtilization",
        "target_average_value": "targetAverageValue",
    },
)
class ResourceMetricSourceV2Beta1:
    def __init__(
        self,
        *,
        name: builtins.str,
        target_average_utilization: typing.Optional[jsii.Number] = None,
        target_average_value: typing.Optional[Quantity] = None,
    ) -> None:
        '''ResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory).  The values will be averaged together before being compared to the target.  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.  Only one "target" type should be set.

        :param name: name is the name of the resource in question.
        :param target_average_utilization: targetAverageUtilization 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.
        :param target_average_value: targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the "pods" metric source type.

        :schema: io.k8s.api.autoscaling.v2beta1.ResourceMetricSource
        '''
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                target_average_utilization: typing.Optional[jsii.Number] = None,
                target_average_value: typing.Optional[Quantity] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument target_average_utilization", value=target_average_utilization, expected_type=type_hints["target_average_utilization"])
            check_type(argname="argument target_average_value", value=target_average_value, expected_type=type_hints["target_average_value"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if target_average_utilization is not None:
            self._values["target_average_utilization"] = target_average_utilization
        if target_average_value is not None:
            self._values["target_average_value"] = target_average_value

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the resource in question.

        :schema: io.k8s.api.autoscaling.v2beta1.ResourceMetricSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target_average_utilization(self) -> typing.Optional[jsii.Number]:
        '''targetAverageUtilization 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.

        :schema: io.k8s.api.autoscaling.v2beta1.ResourceMetricSource#targetAverageUtilization
        '''
        result = self._values.get("target_average_utilization")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def target_average_value(self) -> typing.Optional[Quantity]:
        '''targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the "pods" metric source type.

        :schema: io.k8s.api.autoscaling.v2beta1.ResourceMetricSource#targetAverageValue
        '''
        result = self._values.get("target_average_value")
        return typing.cast(typing.Optional[Quantity], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceMetricSourceV2Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceMetricSourceV2Beta2",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "target": "target"},
)
class ResourceMetricSourceV2Beta2:
    def __init__(
        self,
        *,
        name: builtins.str,
        target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
    ) -> None:
        '''ResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory).  The values will be averaged together before being compared to the target.  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.  Only one "target" type should be set.

        :param name: name is the name of the resource in question.
        :param target: target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ResourceMetricSource
        '''
        if isinstance(target, dict):
            target = MetricTargetV2Beta2(**target)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                target: typing.Union[MetricTargetV2Beta2, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument target", value=target, expected_type=type_hints["target"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "target": target,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''name is the name of the resource in question.

        :schema: io.k8s.api.autoscaling.v2beta2.ResourceMetricSource#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target(self) -> MetricTargetV2Beta2:
        '''target specifies the target value for the given metric.

        :schema: io.k8s.api.autoscaling.v2beta2.ResourceMetricSource#target
        '''
        result = self._values.get("target")
        assert result is not None, "Required property 'target' is missing"
        return typing.cast(MetricTargetV2Beta2, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceMetricSourceV2Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourcePolicyRuleV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "api_groups": "apiGroups",
        "resources": "resources",
        "verbs": "verbs",
        "cluster_scope": "clusterScope",
        "namespaces": "namespaces",
    },
)
class ResourcePolicyRuleV1Beta1:
    def __init__(
        self,
        *,
        api_groups: typing.Sequence[builtins.str],
        resources: typing.Sequence[builtins.str],
        verbs: typing.Sequence[builtins.str],
        cluster_scope: typing.Optional[builtins.bool] = None,
        namespaces: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''ResourcePolicyRule is a predicate that matches some resource requests, testing the request's verb and the target resource.

        A ResourcePolicyRule matches a resource request if and only if: (a) at least one member of verbs matches the request, (b) at least one member of apiGroups matches the request, (c) at least one member of resources matches the request, and (d) either (d1) the request does not specify a namespace (i.e., ``Namespace==""``) and clusterScope is true or (d2) the request specifies a namespace and least one member of namespaces matches the request's namespace.

        :param api_groups: ``apiGroups`` is a list of matching API groups and may not be empty. "*" matches all API groups and, if present, must be the only entry. Required.
        :param resources: ``resources`` is a list of matching resources (i.e., lowercase and plural) with, if desired, subresource. For example, [ "services", "nodes/status" ]. This list may not be empty. "*" matches all resources and, if present, must be the only entry. Required.
        :param verbs: ``verbs`` is a list of matching verbs and may not be empty. "*" matches all verbs and, if present, must be the only entry. Required.
        :param cluster_scope: ``clusterScope`` indicates whether to match requests that do not specify a namespace (which happens either because the resource is not namespaced or the request targets all namespaces). If this field is omitted or false then the ``namespaces`` field must contain a non-empty list.
        :param namespaces: ``namespaces`` is a list of target namespaces that restricts matches. A request that specifies a target namespace matches only if either (a) this list contains that target namespace or (b) this list contains "*". Note that "*" matches any specified namespace but does not match a request that *does not specify* a namespace (see the ``clusterScope`` field for that). This list may be empty, but only if ``clusterScope`` is true.

        :schema: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule
        '''
        if __debug__:
            def stub(
                *,
                api_groups: typing.Sequence[builtins.str],
                resources: typing.Sequence[builtins.str],
                verbs: typing.Sequence[builtins.str],
                cluster_scope: typing.Optional[builtins.bool] = None,
                namespaces: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_groups", value=api_groups, expected_type=type_hints["api_groups"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
            check_type(argname="argument verbs", value=verbs, expected_type=type_hints["verbs"])
            check_type(argname="argument cluster_scope", value=cluster_scope, expected_type=type_hints["cluster_scope"])
            check_type(argname="argument namespaces", value=namespaces, expected_type=type_hints["namespaces"])
        self._values: typing.Dict[str, typing.Any] = {
            "api_groups": api_groups,
            "resources": resources,
            "verbs": verbs,
        }
        if cluster_scope is not None:
            self._values["cluster_scope"] = cluster_scope
        if namespaces is not None:
            self._values["namespaces"] = namespaces

    @builtins.property
    def api_groups(self) -> typing.List[builtins.str]:
        '''``apiGroups`` is a list of matching API groups and may not be empty.

        "*" matches all API groups and, if present, must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule#apiGroups
        '''
        result = self._values.get("api_groups")
        assert result is not None, "Required property 'api_groups' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def resources(self) -> typing.List[builtins.str]:
        '''``resources`` is a list of matching resources (i.e., lowercase and plural) with, if desired, subresource.  For example, [ "services", "nodes/status" ].  This list may not be empty. "*" matches all resources and, if present, must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule#resources
        '''
        result = self._values.get("resources")
        assert result is not None, "Required property 'resources' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def verbs(self) -> typing.List[builtins.str]:
        '''``verbs`` is a list of matching verbs and may not be empty.

        "*" matches all verbs and, if present, must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule#verbs
        '''
        result = self._values.get("verbs")
        assert result is not None, "Required property 'verbs' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def cluster_scope(self) -> typing.Optional[builtins.bool]:
        '''``clusterScope`` indicates whether to match requests that do not specify a namespace (which happens either because the resource is not namespaced or the request targets all namespaces).

        If this field is omitted or false then the ``namespaces`` field must contain a non-empty list.

        :schema: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule#clusterScope
        '''
        result = self._values.get("cluster_scope")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def namespaces(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``namespaces`` is a list of target namespaces that restricts matches.

        A request that specifies a target namespace matches only if either (a) this list contains that target namespace or (b) this list contains "*".  Note that "*" matches any specified namespace but does not match a request that *does not specify* a namespace (see the ``clusterScope`` field for that). This list may be empty, but only if ``clusterScope`` is true.

        :schema: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule#namespaces
        '''
        result = self._values.get("namespaces")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourcePolicyRuleV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourcePolicyRuleV1Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "api_groups": "apiGroups",
        "resources": "resources",
        "verbs": "verbs",
        "cluster_scope": "clusterScope",
        "namespaces": "namespaces",
    },
)
class ResourcePolicyRuleV1Beta2:
    def __init__(
        self,
        *,
        api_groups: typing.Sequence[builtins.str],
        resources: typing.Sequence[builtins.str],
        verbs: typing.Sequence[builtins.str],
        cluster_scope: typing.Optional[builtins.bool] = None,
        namespaces: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''ResourcePolicyRule is a predicate that matches some resource requests, testing the request's verb and the target resource.

        A ResourcePolicyRule matches a resource request if and only if: (a) at least one member of verbs matches the request, (b) at least one member of apiGroups matches the request, (c) at least one member of resources matches the request, and (d) either (d1) the request does not specify a namespace (i.e., ``Namespace==""``) and clusterScope is true or (d2) the request specifies a namespace and least one member of namespaces matches the request's namespace.

        :param api_groups: ``apiGroups`` is a list of matching API groups and may not be empty. "*" matches all API groups and, if present, must be the only entry. Required.
        :param resources: ``resources`` is a list of matching resources (i.e., lowercase and plural) with, if desired, subresource. For example, [ "services", "nodes/status" ]. This list may not be empty. "*" matches all resources and, if present, must be the only entry. Required.
        :param verbs: ``verbs`` is a list of matching verbs and may not be empty. "*" matches all verbs and, if present, must be the only entry. Required.
        :param cluster_scope: ``clusterScope`` indicates whether to match requests that do not specify a namespace (which happens either because the resource is not namespaced or the request targets all namespaces). If this field is omitted or false then the ``namespaces`` field must contain a non-empty list.
        :param namespaces: ``namespaces`` is a list of target namespaces that restricts matches. A request that specifies a target namespace matches only if either (a) this list contains that target namespace or (b) this list contains "*". Note that "*" matches any specified namespace but does not match a request that *does not specify* a namespace (see the ``clusterScope`` field for that). This list may be empty, but only if ``clusterScope`` is true.

        :schema: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule
        '''
        if __debug__:
            def stub(
                *,
                api_groups: typing.Sequence[builtins.str],
                resources: typing.Sequence[builtins.str],
                verbs: typing.Sequence[builtins.str],
                cluster_scope: typing.Optional[builtins.bool] = None,
                namespaces: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_groups", value=api_groups, expected_type=type_hints["api_groups"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
            check_type(argname="argument verbs", value=verbs, expected_type=type_hints["verbs"])
            check_type(argname="argument cluster_scope", value=cluster_scope, expected_type=type_hints["cluster_scope"])
            check_type(argname="argument namespaces", value=namespaces, expected_type=type_hints["namespaces"])
        self._values: typing.Dict[str, typing.Any] = {
            "api_groups": api_groups,
            "resources": resources,
            "verbs": verbs,
        }
        if cluster_scope is not None:
            self._values["cluster_scope"] = cluster_scope
        if namespaces is not None:
            self._values["namespaces"] = namespaces

    @builtins.property
    def api_groups(self) -> typing.List[builtins.str]:
        '''``apiGroups`` is a list of matching API groups and may not be empty.

        "*" matches all API groups and, if present, must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule#apiGroups
        '''
        result = self._values.get("api_groups")
        assert result is not None, "Required property 'api_groups' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def resources(self) -> typing.List[builtins.str]:
        '''``resources`` is a list of matching resources (i.e., lowercase and plural) with, if desired, subresource.  For example, [ "services", "nodes/status" ].  This list may not be empty. "*" matches all resources and, if present, must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule#resources
        '''
        result = self._values.get("resources")
        assert result is not None, "Required property 'resources' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def verbs(self) -> typing.List[builtins.str]:
        '''``verbs`` is a list of matching verbs and may not be empty.

        "*" matches all verbs and, if present, must be the only entry. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule#verbs
        '''
        result = self._values.get("verbs")
        assert result is not None, "Required property 'verbs' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def cluster_scope(self) -> typing.Optional[builtins.bool]:
        '''``clusterScope`` indicates whether to match requests that do not specify a namespace (which happens either because the resource is not namespaced or the request targets all namespaces).

        If this field is omitted or false then the ``namespaces`` field must contain a non-empty list.

        :schema: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule#clusterScope
        '''
        result = self._values.get("cluster_scope")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def namespaces(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``namespaces`` is a list of target namespaces that restricts matches.

        A request that specifies a target namespace matches only if either (a) this list contains that target namespace or (b) this list contains "*".  Note that "*" matches any specified namespace but does not match a request that *does not specify* a namespace (see the ``clusterScope`` field for that). This list may be empty, but only if ``clusterScope`` is true.

        :schema: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule#namespaces
        '''
        result = self._values.get("namespaces")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourcePolicyRuleV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceQuotaSpec",
    jsii_struct_bases=[],
    name_mapping={
        "hard": "hard",
        "scopes": "scopes",
        "scope_selector": "scopeSelector",
    },
)
class ResourceQuotaSpec:
    def __init__(
        self,
        *,
        hard: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
        scopes: typing.Optional[typing.Sequence[builtins.str]] = None,
        scope_selector: typing.Optional[typing.Union["ScopeSelector", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''ResourceQuotaSpec defines the desired hard limits to enforce for Quota.

        :param hard: hard is the set of desired hard limits for each named resource. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
        :param scopes: A collection of filters that must match each object tracked by a quota. If not specified, the quota matches all objects.
        :param scope_selector: scopeSelector is also a collection of filters like scopes that must match each object tracked by a quota but expressed using ScopeSelectorOperator in combination with possible values. For a resource to match, both scopes AND scopeSelector (if specified in spec), must be matched.

        :schema: io.k8s.api.core.v1.ResourceQuotaSpec
        '''
        if isinstance(scope_selector, dict):
            scope_selector = ScopeSelector(**scope_selector)
        if __debug__:
            def stub(
                *,
                hard: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                scopes: typing.Optional[typing.Sequence[builtins.str]] = None,
                scope_selector: typing.Optional[typing.Union[ScopeSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument hard", value=hard, expected_type=type_hints["hard"])
            check_type(argname="argument scopes", value=scopes, expected_type=type_hints["scopes"])
            check_type(argname="argument scope_selector", value=scope_selector, expected_type=type_hints["scope_selector"])
        self._values: typing.Dict[str, typing.Any] = {}
        if hard is not None:
            self._values["hard"] = hard
        if scopes is not None:
            self._values["scopes"] = scopes
        if scope_selector is not None:
            self._values["scope_selector"] = scope_selector

    @builtins.property
    def hard(self) -> typing.Optional[typing.Mapping[builtins.str, Quantity]]:
        '''hard is the set of desired hard limits for each named resource.

        More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/

        :schema: io.k8s.api.core.v1.ResourceQuotaSpec#hard
        '''
        result = self._values.get("hard")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, Quantity]], result)

    @builtins.property
    def scopes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''A collection of filters that must match each object tracked by a quota.

        If not specified, the quota matches all objects.

        :schema: io.k8s.api.core.v1.ResourceQuotaSpec#scopes
        '''
        result = self._values.get("scopes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def scope_selector(self) -> typing.Optional["ScopeSelector"]:
        '''scopeSelector is also a collection of filters like scopes that must match each object tracked by a quota but expressed using ScopeSelectorOperator in combination with possible values.

        For a resource to match, both scopes AND scopeSelector (if specified in spec), must be matched.

        :schema: io.k8s.api.core.v1.ResourceQuotaSpec#scopeSelector
        '''
        result = self._values.get("scope_selector")
        return typing.cast(typing.Optional["ScopeSelector"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceQuotaSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ResourceRequirements",
    jsii_struct_bases=[],
    name_mapping={"limits": "limits", "requests": "requests"},
)
class ResourceRequirements:
    def __init__(
        self,
        *,
        limits: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
        requests: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
    ) -> None:
        '''ResourceRequirements describes the compute resource requirements.

        :param limits: Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        :param requests: Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

        :schema: io.k8s.api.core.v1.ResourceRequirements
        '''
        if __debug__:
            def stub(
                *,
                limits: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
                requests: typing.Optional[typing.Mapping[builtins.str, Quantity]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument limits", value=limits, expected_type=type_hints["limits"])
            check_type(argname="argument requests", value=requests, expected_type=type_hints["requests"])
        self._values: typing.Dict[str, typing.Any] = {}
        if limits is not None:
            self._values["limits"] = limits
        if requests is not None:
            self._values["requests"] = requests

    @builtins.property
    def limits(self) -> typing.Optional[typing.Mapping[builtins.str, Quantity]]:
        '''Limits describes the maximum amount of compute resources allowed.

        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

        :schema: io.k8s.api.core.v1.ResourceRequirements#limits
        '''
        result = self._values.get("limits")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, Quantity]], result)

    @builtins.property
    def requests(self) -> typing.Optional[typing.Mapping[builtins.str, Quantity]]:
        '''Requests describes the minimum amount of compute resources required.

        If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

        :schema: io.k8s.api.core.v1.ResourceRequirements#requests
        '''
        result = self._values.get("requests")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, Quantity]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ResourceRequirements(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RoleRef",
    jsii_struct_bases=[],
    name_mapping={"api_group": "apiGroup", "kind": "kind", "name": "name"},
)
class RoleRef:
    def __init__(
        self,
        *,
        api_group: builtins.str,
        kind: builtins.str,
        name: builtins.str,
    ) -> None:
        '''RoleRef contains information that points to the role being used.

        :param api_group: APIGroup is the group for the resource being referenced.
        :param kind: Kind is the type of resource being referenced.
        :param name: Name is the name of resource being referenced.

        :schema: io.k8s.api.rbac.v1.RoleRef
        '''
        if __debug__:
            def stub(
                *,
                api_group: builtins.str,
                kind: builtins.str,
                name: builtins.str,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_group", value=api_group, expected_type=type_hints["api_group"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "api_group": api_group,
            "kind": kind,
            "name": name,
        }

    @builtins.property
    def api_group(self) -> builtins.str:
        '''APIGroup is the group for the resource being referenced.

        :schema: io.k8s.api.rbac.v1.RoleRef#apiGroup
        '''
        result = self._values.get("api_group")
        assert result is not None, "Required property 'api_group' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind is the type of resource being referenced.

        :schema: io.k8s.api.rbac.v1.RoleRef#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the name of resource being referenced.

        :schema: io.k8s.api.rbac.v1.RoleRef#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RoleRef(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RollingUpdateDaemonSet",
    jsii_struct_bases=[],
    name_mapping={"max_surge": "maxSurge", "max_unavailable": "maxUnavailable"},
)
class RollingUpdateDaemonSet:
    def __init__(
        self,
        *,
        max_surge: typing.Optional[IntOrString] = None,
        max_unavailable: typing.Optional[IntOrString] = None,
    ) -> None:
        '''Spec to control the desired behavior of daemon set rolling update.

        :param max_surge: The maximum number of nodes with an existing available DaemonSet pod that can have an updated DaemonSet pod during during an update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up to a minimum of 1. Default value is 0. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their a new pod created before the old pod is marked as deleted. The update starts by launching new pods on 30% of nodes. Once an updated pod is available (Ready for at least minReadySeconds) the old DaemonSet pod on that node is marked deleted. If the old pod becomes unavailable for any reason (Ready transitions to false, is evicted, or is drained) an updated pod is immediatedly created on that node without considering surge limits. Allowing surge implies the possibility that the resources consumed by the daemonset on any given node can double if the readiness check fails, and so resource intensive daemonsets should take into account that they may cause evictions during disruption. This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.
        :param max_unavailable: The maximum number of DaemonSet pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of total number of DaemonSet pods at the start of the update (ex: 10%). Absolute number is calculated from percentage by rounding up. This cannot be 0 if MaxSurge is 0 Default value is 1. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their pods stopped for an update at any given time. The update starts by stopping at most 30% of those DaemonSet pods and then brings up new DaemonSet pods in their place. Once the new pods are available, it then proceeds onto other DaemonSet pods, thus ensuring that at least 70% of original number of DaemonSet pods are available at all times during the update.

        :schema: io.k8s.api.apps.v1.RollingUpdateDaemonSet
        '''
        if __debug__:
            def stub(
                *,
                max_surge: typing.Optional[IntOrString] = None,
                max_unavailable: typing.Optional[IntOrString] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_surge", value=max_surge, expected_type=type_hints["max_surge"])
            check_type(argname="argument max_unavailable", value=max_unavailable, expected_type=type_hints["max_unavailable"])
        self._values: typing.Dict[str, typing.Any] = {}
        if max_surge is not None:
            self._values["max_surge"] = max_surge
        if max_unavailable is not None:
            self._values["max_unavailable"] = max_unavailable

    @builtins.property
    def max_surge(self) -> typing.Optional[IntOrString]:
        '''The maximum number of nodes with an existing available DaemonSet pod that can have an updated DaemonSet pod during during an update.

        Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up to a minimum of 1. Default value is 0. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their a new pod created before the old pod is marked as deleted. The update starts by launching new pods on 30% of nodes. Once an updated pod is available (Ready for at least minReadySeconds) the old DaemonSet pod on that node is marked deleted. If the old pod becomes unavailable for any reason (Ready transitions to false, is evicted, or is drained) an updated pod is immediatedly created on that node without considering surge limits. Allowing surge implies the possibility that the resources consumed by the daemonset on any given node can double if the readiness check fails, and so resource intensive daemonsets should take into account that they may cause evictions during disruption. This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.

        :schema: io.k8s.api.apps.v1.RollingUpdateDaemonSet#maxSurge
        '''
        result = self._values.get("max_surge")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def max_unavailable(self) -> typing.Optional[IntOrString]:
        '''The maximum number of DaemonSet pods that can be unavailable during the update.

        Value can be an absolute number (ex: 5) or a percentage of total number of DaemonSet pods at the start of the update (ex: 10%). Absolute number is calculated from percentage by rounding up. This cannot be 0 if MaxSurge is 0 Default value is 1. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their pods stopped for an update at any given time. The update starts by stopping at most 30% of those DaemonSet pods and then brings up new DaemonSet pods in their place. Once the new pods are available, it then proceeds onto other DaemonSet pods, thus ensuring that at least 70% of original number of DaemonSet pods are available at all times during the update.

        :schema: io.k8s.api.apps.v1.RollingUpdateDaemonSet#maxUnavailable
        '''
        result = self._values.get("max_unavailable")
        return typing.cast(typing.Optional[IntOrString], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RollingUpdateDaemonSet(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RollingUpdateDeployment",
    jsii_struct_bases=[],
    name_mapping={"max_surge": "maxSurge", "max_unavailable": "maxUnavailable"},
)
class RollingUpdateDeployment:
    def __init__(
        self,
        *,
        max_surge: typing.Optional[IntOrString] = None,
        max_unavailable: typing.Optional[IntOrString] = None,
    ) -> None:
        '''Spec to control the desired behavior of rolling update.

        :param max_surge: The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods. Default: 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods.
        :param max_unavailable: The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods. Default: 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.

        :schema: io.k8s.api.apps.v1.RollingUpdateDeployment
        '''
        if __debug__:
            def stub(
                *,
                max_surge: typing.Optional[IntOrString] = None,
                max_unavailable: typing.Optional[IntOrString] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_surge", value=max_surge, expected_type=type_hints["max_surge"])
            check_type(argname="argument max_unavailable", value=max_unavailable, expected_type=type_hints["max_unavailable"])
        self._values: typing.Dict[str, typing.Any] = {}
        if max_surge is not None:
            self._values["max_surge"] = max_surge
        if max_unavailable is not None:
            self._values["max_unavailable"] = max_unavailable

    @builtins.property
    def max_surge(self) -> typing.Optional[IntOrString]:
        '''The maximum number of pods that can be scheduled above the desired number of pods.

        Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods.

        :default: 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods.

        :schema: io.k8s.api.apps.v1.RollingUpdateDeployment#maxSurge
        '''
        result = self._values.get("max_surge")
        return typing.cast(typing.Optional[IntOrString], result)

    @builtins.property
    def max_unavailable(self) -> typing.Optional[IntOrString]:
        '''The maximum number of pods that can be unavailable during the update.

        Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.

        :default: 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.

        :schema: io.k8s.api.apps.v1.RollingUpdateDeployment#maxUnavailable
        '''
        result = self._values.get("max_unavailable")
        return typing.cast(typing.Optional[IntOrString], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RollingUpdateDeployment(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RollingUpdateStatefulSetStrategy",
    jsii_struct_bases=[],
    name_mapping={"partition": "partition"},
)
class RollingUpdateStatefulSetStrategy:
    def __init__(self, *, partition: typing.Optional[jsii.Number] = None) -> None:
        '''RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.

        :param partition: Partition indicates the ordinal at which the StatefulSet should be partitioned. Default value is 0.

        :schema: io.k8s.api.apps.v1.RollingUpdateStatefulSetStrategy
        '''
        if __debug__:
            def stub(*, partition: typing.Optional[jsii.Number] = None) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument partition", value=partition, expected_type=type_hints["partition"])
        self._values: typing.Dict[str, typing.Any] = {}
        if partition is not None:
            self._values["partition"] = partition

    @builtins.property
    def partition(self) -> typing.Optional[jsii.Number]:
        '''Partition indicates the ordinal at which the StatefulSet should be partitioned.

        Default value is 0.

        :schema: io.k8s.api.apps.v1.RollingUpdateStatefulSetStrategy#partition
        '''
        result = self._values.get("partition")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RollingUpdateStatefulSetStrategy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RuleWithOperations",
    jsii_struct_bases=[],
    name_mapping={
        "api_groups": "apiGroups",
        "api_versions": "apiVersions",
        "operations": "operations",
        "resources": "resources",
        "scope": "scope",
    },
)
class RuleWithOperations:
    def __init__(
        self,
        *,
        api_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
        api_versions: typing.Optional[typing.Sequence[builtins.str]] = None,
        operations: typing.Optional[typing.Sequence[builtins.str]] = None,
        resources: typing.Optional[typing.Sequence[builtins.str]] = None,
        scope: typing.Optional[builtins.str] = None,
    ) -> None:
        '''RuleWithOperations is a tuple of Operations and Resources.

        It is recommended to make sure that all the tuple expansions are valid.

        :param api_groups: APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required.
        :param api_versions: APIVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required.
        :param operations: Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required.
        :param resources: Resources is a list of resources this rule applies to. For example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources. If wildcard is present, the validation rule will ensure resources do not overlap with each other. Depending on the enclosing object, subresources might not be allowed. Required.
        :param scope: scope specifies the scope of this rule. Valid values are "Cluster", "Namespaced", and "*" "Cluster" means that only cluster-scoped resources will match this rule. Namespace API objects are cluster-scoped. "Namespaced" means that only namespaced resources will match this rule. "*" means that there are no scope restrictions. Subresources match the scope of their parent resource. Default is "*". Default: .

        :schema: io.k8s.api.admissionregistration.v1.RuleWithOperations
        '''
        if __debug__:
            def stub(
                *,
                api_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
                api_versions: typing.Optional[typing.Sequence[builtins.str]] = None,
                operations: typing.Optional[typing.Sequence[builtins.str]] = None,
                resources: typing.Optional[typing.Sequence[builtins.str]] = None,
                scope: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument api_groups", value=api_groups, expected_type=type_hints["api_groups"])
            check_type(argname="argument api_versions", value=api_versions, expected_type=type_hints["api_versions"])
            check_type(argname="argument operations", value=operations, expected_type=type_hints["operations"])
            check_type(argname="argument resources", value=resources, expected_type=type_hints["resources"])
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        self._values: typing.Dict[str, typing.Any] = {}
        if api_groups is not None:
            self._values["api_groups"] = api_groups
        if api_versions is not None:
            self._values["api_versions"] = api_versions
        if operations is not None:
            self._values["operations"] = operations
        if resources is not None:
            self._values["resources"] = resources
        if scope is not None:
            self._values["scope"] = scope

    @builtins.property
    def api_groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''APIGroups is the API groups the resources belong to.

        '*' is all groups. If '*' is present, the length of the slice must be one. Required.

        :schema: io.k8s.api.admissionregistration.v1.RuleWithOperations#apiGroups
        '''
        result = self._values.get("api_groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def api_versions(self) -> typing.Optional[typing.List[builtins.str]]:
        '''APIVersions is the API versions the resources belong to.

        '*' is all versions. If '*' is present, the length of the slice must be one. Required.

        :schema: io.k8s.api.admissionregistration.v1.RuleWithOperations#apiVersions
        '''
        result = self._values.get("api_versions")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def operations(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added.

        If '*' is present, the length of the slice must be one. Required.

        :schema: io.k8s.api.admissionregistration.v1.RuleWithOperations#operations
        '''
        result = self._values.get("operations")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def resources(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Resources is a list of resources this rule applies to.

        For example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources.

        If wildcard is present, the validation rule will ensure resources do not overlap with each other.

        Depending on the enclosing object, subresources might not be allowed. Required.

        :schema: io.k8s.api.admissionregistration.v1.RuleWithOperations#resources
        '''
        result = self._values.get("resources")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def scope(self) -> typing.Optional[builtins.str]:
        '''scope specifies the scope of this rule.

        Valid values are "Cluster", "Namespaced", and "*" "Cluster" means that only cluster-scoped resources will match this rule. Namespace API objects are cluster-scoped. "Namespaced" means that only namespaced resources will match this rule. "*" means that there are no scope restrictions. Subresources match the scope of their parent resource. Default is "*".

        :default: .

        :schema: io.k8s.api.admissionregistration.v1.RuleWithOperations#scope
        '''
        result = self._values.get("scope")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RuleWithOperations(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RunAsGroupStrategyOptionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"rule": "rule", "ranges": "ranges"},
)
class RunAsGroupStrategyOptionsV1Beta1:
    def __init__(
        self,
        *,
        rule: builtins.str,
        ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy.

        :param rule: rule is the strategy that will dictate the allowable RunAsGroup values that may be set.
        :param ranges: ranges are the allowed ranges of gids that may be used. If you would like to force a single gid then supply a single range with the same start and end. Required for MustRunAs.

        :schema: io.k8s.api.policy.v1beta1.RunAsGroupStrategyOptions
        '''
        if __debug__:
            def stub(
                *,
                rule: builtins.str,
                ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rule", value=rule, expected_type=type_hints["rule"])
            check_type(argname="argument ranges", value=ranges, expected_type=type_hints["ranges"])
        self._values: typing.Dict[str, typing.Any] = {
            "rule": rule,
        }
        if ranges is not None:
            self._values["ranges"] = ranges

    @builtins.property
    def rule(self) -> builtins.str:
        '''rule is the strategy that will dictate the allowable RunAsGroup values that may be set.

        :schema: io.k8s.api.policy.v1beta1.RunAsGroupStrategyOptions#rule
        '''
        result = self._values.get("rule")
        assert result is not None, "Required property 'rule' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def ranges(self) -> typing.Optional[typing.List[IdRangeV1Beta1]]:
        '''ranges are the allowed ranges of gids that may be used.

        If you would like to force a single gid then supply a single range with the same start and end. Required for MustRunAs.

        :schema: io.k8s.api.policy.v1beta1.RunAsGroupStrategyOptions#ranges
        '''
        result = self._values.get("ranges")
        return typing.cast(typing.Optional[typing.List[IdRangeV1Beta1]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RunAsGroupStrategyOptionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RunAsUserStrategyOptionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"rule": "rule", "ranges": "ranges"},
)
class RunAsUserStrategyOptionsV1Beta1:
    def __init__(
        self,
        *,
        rule: builtins.str,
        ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy.

        :param rule: rule is the strategy that will dictate the allowable RunAsUser values that may be set.
        :param ranges: ranges are the allowed ranges of uids that may be used. If you would like to force a single uid then supply a single range with the same start and end. Required for MustRunAs.

        :schema: io.k8s.api.policy.v1beta1.RunAsUserStrategyOptions
        '''
        if __debug__:
            def stub(
                *,
                rule: builtins.str,
                ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rule", value=rule, expected_type=type_hints["rule"])
            check_type(argname="argument ranges", value=ranges, expected_type=type_hints["ranges"])
        self._values: typing.Dict[str, typing.Any] = {
            "rule": rule,
        }
        if ranges is not None:
            self._values["ranges"] = ranges

    @builtins.property
    def rule(self) -> builtins.str:
        '''rule is the strategy that will dictate the allowable RunAsUser values that may be set.

        :schema: io.k8s.api.policy.v1beta1.RunAsUserStrategyOptions#rule
        '''
        result = self._values.get("rule")
        assert result is not None, "Required property 'rule' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def ranges(self) -> typing.Optional[typing.List[IdRangeV1Beta1]]:
        '''ranges are the allowed ranges of uids that may be used.

        If you would like to force a single uid then supply a single range with the same start and end. Required for MustRunAs.

        :schema: io.k8s.api.policy.v1beta1.RunAsUserStrategyOptions#ranges
        '''
        result = self._values.get("ranges")
        return typing.cast(typing.Optional[typing.List[IdRangeV1Beta1]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RunAsUserStrategyOptionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RuntimeClassSpecV1Alpha1",
    jsii_struct_bases=[],
    name_mapping={
        "runtime_handler": "runtimeHandler",
        "overhead": "overhead",
        "scheduling": "scheduling",
    },
)
class RuntimeClassSpecV1Alpha1:
    def __init__(
        self,
        *,
        runtime_handler: builtins.str,
        overhead: typing.Optional[typing.Union[OverheadV1Alpha1, typing.Dict[str, typing.Any]]] = None,
        scheduling: typing.Optional[typing.Union["SchedulingV1Alpha1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''RuntimeClassSpec is a specification of a RuntimeClass.

        It contains parameters that are required to describe the RuntimeClass to the Container Runtime Interface (CRI) implementation, as well as any other components that need to understand how the pod will be run. The RuntimeClassSpec is immutable.

        :param runtime_handler: RuntimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.
        :param overhead: Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
        :param scheduling: Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassSpec
        '''
        if isinstance(overhead, dict):
            overhead = OverheadV1Alpha1(**overhead)
        if isinstance(scheduling, dict):
            scheduling = SchedulingV1Alpha1(**scheduling)
        if __debug__:
            def stub(
                *,
                runtime_handler: builtins.str,
                overhead: typing.Optional[typing.Union[OverheadV1Alpha1, typing.Dict[str, typing.Any]]] = None,
                scheduling: typing.Optional[typing.Union[SchedulingV1Alpha1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument runtime_handler", value=runtime_handler, expected_type=type_hints["runtime_handler"])
            check_type(argname="argument overhead", value=overhead, expected_type=type_hints["overhead"])
            check_type(argname="argument scheduling", value=scheduling, expected_type=type_hints["scheduling"])
        self._values: typing.Dict[str, typing.Any] = {
            "runtime_handler": runtime_handler,
        }
        if overhead is not None:
            self._values["overhead"] = overhead
        if scheduling is not None:
            self._values["scheduling"] = scheduling

    @builtins.property
    def runtime_handler(self) -> builtins.str:
        '''RuntimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class.

        The possible values are specific to the node & CRI configuration.  It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called "runc" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassSpec#runtimeHandler
        '''
        result = self._values.get("runtime_handler")
        assert result is not None, "Required property 'runtime_handler' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def overhead(self) -> typing.Optional[OverheadV1Alpha1]:
        '''Overhead represents the resource overhead associated with running a pod for a given RuntimeClass.

        For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassSpec#overhead
        '''
        result = self._values.get("overhead")
        return typing.cast(typing.Optional[OverheadV1Alpha1], result)

    @builtins.property
    def scheduling(self) -> typing.Optional["SchedulingV1Alpha1"]:
        '''Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it.

        If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.

        :schema: io.k8s.api.node.v1alpha1.RuntimeClassSpec#scheduling
        '''
        result = self._values.get("scheduling")
        return typing.cast(typing.Optional["SchedulingV1Alpha1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RuntimeClassSpecV1Alpha1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.RuntimeClassStrategyOptionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "allowed_runtime_class_names": "allowedRuntimeClassNames",
        "default_runtime_class_name": "defaultRuntimeClassName",
    },
)
class RuntimeClassStrategyOptionsV1Beta1:
    def __init__(
        self,
        *,
        allowed_runtime_class_names: typing.Sequence[builtins.str],
        default_runtime_class_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses for a pod.

        :param allowed_runtime_class_names: allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the list. An empty list requires the RuntimeClassName field to be unset.
        :param default_runtime_class_name: defaultRuntimeClassName is the default RuntimeClassName to set on the pod. The default MUST be allowed by the allowedRuntimeClassNames list. A value of nil does not mutate the Pod.

        :schema: io.k8s.api.policy.v1beta1.RuntimeClassStrategyOptions
        '''
        if __debug__:
            def stub(
                *,
                allowed_runtime_class_names: typing.Sequence[builtins.str],
                default_runtime_class_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument allowed_runtime_class_names", value=allowed_runtime_class_names, expected_type=type_hints["allowed_runtime_class_names"])
            check_type(argname="argument default_runtime_class_name", value=default_runtime_class_name, expected_type=type_hints["default_runtime_class_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "allowed_runtime_class_names": allowed_runtime_class_names,
        }
        if default_runtime_class_name is not None:
            self._values["default_runtime_class_name"] = default_runtime_class_name

    @builtins.property
    def allowed_runtime_class_names(self) -> typing.List[builtins.str]:
        '''allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod.

        A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the list. An empty list requires the RuntimeClassName field to be unset.

        :schema: io.k8s.api.policy.v1beta1.RuntimeClassStrategyOptions#allowedRuntimeClassNames
        '''
        result = self._values.get("allowed_runtime_class_names")
        assert result is not None, "Required property 'allowed_runtime_class_names' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def default_runtime_class_name(self) -> typing.Optional[builtins.str]:
        '''defaultRuntimeClassName is the default RuntimeClassName to set on the pod.

        The default MUST be allowed by the allowedRuntimeClassNames list. A value of nil does not mutate the Pod.

        :schema: io.k8s.api.policy.v1beta1.RuntimeClassStrategyOptions#defaultRuntimeClassName
        '''
        result = self._values.get("default_runtime_class_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RuntimeClassStrategyOptionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ScaleIoPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "gateway": "gateway",
        "secret_ref": "secretRef",
        "system": "system",
        "fs_type": "fsType",
        "protection_domain": "protectionDomain",
        "read_only": "readOnly",
        "ssl_enabled": "sslEnabled",
        "storage_mode": "storageMode",
        "storage_pool": "storagePool",
        "volume_name": "volumeName",
    },
)
class ScaleIoPersistentVolumeSource:
    def __init__(
        self,
        *,
        gateway: builtins.str,
        secret_ref: typing.Union["SecretReference", typing.Dict[str, typing.Any]],
        system: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        protection_domain: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        ssl_enabled: typing.Optional[builtins.bool] = None,
        storage_mode: typing.Optional[builtins.str] = None,
        storage_pool: typing.Optional[builtins.str] = None,
        volume_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ScaleIOPersistentVolumeSource represents a persistent ScaleIO volume.

        :param gateway: The host address of the ScaleIO API Gateway.
        :param secret_ref: SecretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail.
        :param system: The name of the storage system as configured in ScaleIO.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs" Default: xfs"
        :param protection_domain: The name of the ScaleIO Protection Domain for the configured storage.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param ssl_enabled: Flag to enable/disable SSL communication with Gateway, default false.
        :param storage_mode: Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. Default: ThinProvisioned.
        :param storage_pool: The ScaleIO Storage Pool associated with the protection domain.
        :param volume_name: The name of a volume already created in the ScaleIO system that is associated with this volume source.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = SecretReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                gateway: builtins.str,
                secret_ref: typing.Union[SecretReference, typing.Dict[str, typing.Any]],
                system: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                protection_domain: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                ssl_enabled: typing.Optional[builtins.bool] = None,
                storage_mode: typing.Optional[builtins.str] = None,
                storage_pool: typing.Optional[builtins.str] = None,
                volume_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument gateway", value=gateway, expected_type=type_hints["gateway"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument system", value=system, expected_type=type_hints["system"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument protection_domain", value=protection_domain, expected_type=type_hints["protection_domain"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument ssl_enabled", value=ssl_enabled, expected_type=type_hints["ssl_enabled"])
            check_type(argname="argument storage_mode", value=storage_mode, expected_type=type_hints["storage_mode"])
            check_type(argname="argument storage_pool", value=storage_pool, expected_type=type_hints["storage_pool"])
            check_type(argname="argument volume_name", value=volume_name, expected_type=type_hints["volume_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "gateway": gateway,
            "secret_ref": secret_ref,
            "system": system,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if protection_domain is not None:
            self._values["protection_domain"] = protection_domain
        if read_only is not None:
            self._values["read_only"] = read_only
        if ssl_enabled is not None:
            self._values["ssl_enabled"] = ssl_enabled
        if storage_mode is not None:
            self._values["storage_mode"] = storage_mode
        if storage_pool is not None:
            self._values["storage_pool"] = storage_pool
        if volume_name is not None:
            self._values["volume_name"] = volume_name

    @builtins.property
    def gateway(self) -> builtins.str:
        '''The host address of the ScaleIO API Gateway.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#gateway
        '''
        result = self._values.get("gateway")
        assert result is not None, "Required property 'gateway' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def secret_ref(self) -> "SecretReference":
        '''SecretRef references to the secret for ScaleIO user and other sensitive information.

        If this is not provided, Login operation will fail.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        assert result is not None, "Required property 'secret_ref' is missing"
        return typing.cast("SecretReference", result)

    @builtins.property
    def system(self) -> builtins.str:
        '''The name of the storage system as configured in ScaleIO.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#system
        '''
        result = self._values.get("system")
        assert result is not None, "Required property 'system' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs"

        :default: xfs"

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def protection_domain(self) -> typing.Optional[builtins.str]:
        '''The name of the ScaleIO Protection Domain for the configured storage.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#protectionDomain
        '''
        result = self._values.get("protection_domain")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ssl_enabled(self) -> typing.Optional[builtins.bool]:
        '''Flag to enable/disable SSL communication with Gateway, default false.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#sslEnabled
        '''
        result = self._values.get("ssl_enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def storage_mode(self) -> typing.Optional[builtins.str]:
        '''Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.

        Default is ThinProvisioned.

        :default: ThinProvisioned.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#storageMode
        '''
        result = self._values.get("storage_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def storage_pool(self) -> typing.Optional[builtins.str]:
        '''The ScaleIO Storage Pool associated with the protection domain.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#storagePool
        '''
        result = self._values.get("storage_pool")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_name(self) -> typing.Optional[builtins.str]:
        '''The name of a volume already created in the ScaleIO system that is associated with this volume source.

        :schema: io.k8s.api.core.v1.ScaleIOPersistentVolumeSource#volumeName
        '''
        result = self._values.get("volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ScaleIoPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ScaleIoVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "gateway": "gateway",
        "secret_ref": "secretRef",
        "system": "system",
        "fs_type": "fsType",
        "protection_domain": "protectionDomain",
        "read_only": "readOnly",
        "ssl_enabled": "sslEnabled",
        "storage_mode": "storageMode",
        "storage_pool": "storagePool",
        "volume_name": "volumeName",
    },
)
class ScaleIoVolumeSource:
    def __init__(
        self,
        *,
        gateway: builtins.str,
        secret_ref: typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]],
        system: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        protection_domain: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        ssl_enabled: typing.Optional[builtins.bool] = None,
        storage_mode: typing.Optional[builtins.str] = None,
        storage_pool: typing.Optional[builtins.str] = None,
        volume_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ScaleIOVolumeSource represents a persistent ScaleIO volume.

        :param gateway: The host address of the ScaleIO API Gateway.
        :param secret_ref: SecretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail.
        :param system: The name of the storage system as configured in ScaleIO.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". Default: xfs".
        :param protection_domain: The name of the ScaleIO Protection Domain for the configured storage.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param ssl_enabled: Flag to enable/disable SSL communication with Gateway, default false.
        :param storage_mode: Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. Default: ThinProvisioned.
        :param storage_pool: The ScaleIO Storage Pool associated with the protection domain.
        :param volume_name: The name of a volume already created in the ScaleIO system that is associated with this volume source.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                gateway: builtins.str,
                secret_ref: typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]],
                system: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                protection_domain: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                ssl_enabled: typing.Optional[builtins.bool] = None,
                storage_mode: typing.Optional[builtins.str] = None,
                storage_pool: typing.Optional[builtins.str] = None,
                volume_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument gateway", value=gateway, expected_type=type_hints["gateway"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument system", value=system, expected_type=type_hints["system"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument protection_domain", value=protection_domain, expected_type=type_hints["protection_domain"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument ssl_enabled", value=ssl_enabled, expected_type=type_hints["ssl_enabled"])
            check_type(argname="argument storage_mode", value=storage_mode, expected_type=type_hints["storage_mode"])
            check_type(argname="argument storage_pool", value=storage_pool, expected_type=type_hints["storage_pool"])
            check_type(argname="argument volume_name", value=volume_name, expected_type=type_hints["volume_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "gateway": gateway,
            "secret_ref": secret_ref,
            "system": system,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if protection_domain is not None:
            self._values["protection_domain"] = protection_domain
        if read_only is not None:
            self._values["read_only"] = read_only
        if ssl_enabled is not None:
            self._values["ssl_enabled"] = ssl_enabled
        if storage_mode is not None:
            self._values["storage_mode"] = storage_mode
        if storage_pool is not None:
            self._values["storage_pool"] = storage_pool
        if volume_name is not None:
            self._values["volume_name"] = volume_name

    @builtins.property
    def gateway(self) -> builtins.str:
        '''The host address of the ScaleIO API Gateway.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#gateway
        '''
        result = self._values.get("gateway")
        assert result is not None, "Required property 'gateway' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def secret_ref(self) -> LocalObjectReference:
        '''SecretRef references to the secret for ScaleIO user and other sensitive information.

        If this is not provided, Login operation will fail.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        assert result is not None, "Required property 'secret_ref' is missing"
        return typing.cast(LocalObjectReference, result)

    @builtins.property
    def system(self) -> builtins.str:
        '''The name of the storage system as configured in ScaleIO.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#system
        '''
        result = self._values.get("system")
        assert result is not None, "Required property 'system' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs".

        :default: xfs".

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def protection_domain(self) -> typing.Optional[builtins.str]:
        '''The name of the ScaleIO Protection Domain for the configured storage.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#protectionDomain
        '''
        result = self._values.get("protection_domain")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ssl_enabled(self) -> typing.Optional[builtins.bool]:
        '''Flag to enable/disable SSL communication with Gateway, default false.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#sslEnabled
        '''
        result = self._values.get("ssl_enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def storage_mode(self) -> typing.Optional[builtins.str]:
        '''Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.

        Default is ThinProvisioned.

        :default: ThinProvisioned.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#storageMode
        '''
        result = self._values.get("storage_mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def storage_pool(self) -> typing.Optional[builtins.str]:
        '''The ScaleIO Storage Pool associated with the protection domain.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#storagePool
        '''
        result = self._values.get("storage_pool")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_name(self) -> typing.Optional[builtins.str]:
        '''The name of a volume already created in the ScaleIO system that is associated with this volume source.

        :schema: io.k8s.api.core.v1.ScaleIOVolumeSource#volumeName
        '''
        result = self._values.get("volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ScaleIoVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ScaleSpec",
    jsii_struct_bases=[],
    name_mapping={"replicas": "replicas"},
)
class ScaleSpec:
    def __init__(self, *, replicas: typing.Optional[jsii.Number] = None) -> None:
        '''ScaleSpec describes the attributes of a scale subresource.

        :param replicas: desired number of instances for the scaled object.

        :schema: io.k8s.api.autoscaling.v1.ScaleSpec
        '''
        if __debug__:
            def stub(*, replicas: typing.Optional[jsii.Number] = None) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument replicas", value=replicas, expected_type=type_hints["replicas"])
        self._values: typing.Dict[str, typing.Any] = {}
        if replicas is not None:
            self._values["replicas"] = replicas

    @builtins.property
    def replicas(self) -> typing.Optional[jsii.Number]:
        '''desired number of instances for the scaled object.

        :schema: io.k8s.api.autoscaling.v1.ScaleSpec#replicas
        '''
        result = self._values.get("replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ScaleSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Scheduling",
    jsii_struct_bases=[],
    name_mapping={"node_selector": "nodeSelector", "tolerations": "tolerations"},
)
class Scheduling:
    def __init__(
        self,
        *,
        node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        tolerations: typing.Optional[typing.Sequence[typing.Union["Toleration", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.

        :param node_selector: nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.
        :param tolerations: tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.

        :schema: io.k8s.api.node.v1.Scheduling
        '''
        if __debug__:
            def stub(
                *,
                node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                tolerations: typing.Optional[typing.Sequence[typing.Union[Toleration, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument node_selector", value=node_selector, expected_type=type_hints["node_selector"])
            check_type(argname="argument tolerations", value=tolerations, expected_type=type_hints["tolerations"])
        self._values: typing.Dict[str, typing.Any] = {}
        if node_selector is not None:
            self._values["node_selector"] = node_selector
        if tolerations is not None:
            self._values["tolerations"] = tolerations

    @builtins.property
    def node_selector(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''nodeSelector lists labels that must be present on nodes that support this RuntimeClass.

        Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.

        :schema: io.k8s.api.node.v1.Scheduling#nodeSelector
        '''
        result = self._values.get("node_selector")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def tolerations(self) -> typing.Optional[typing.List["Toleration"]]:
        '''tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.

        :schema: io.k8s.api.node.v1.Scheduling#tolerations
        '''
        result = self._values.get("tolerations")
        return typing.cast(typing.Optional[typing.List["Toleration"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Scheduling(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SchedulingV1Alpha1",
    jsii_struct_bases=[],
    name_mapping={"node_selector": "nodeSelector", "tolerations": "tolerations"},
)
class SchedulingV1Alpha1:
    def __init__(
        self,
        *,
        node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        tolerations: typing.Optional[typing.Sequence[typing.Union["Toleration", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.

        :param node_selector: nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.
        :param tolerations: tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.

        :schema: io.k8s.api.node.v1alpha1.Scheduling
        '''
        if __debug__:
            def stub(
                *,
                node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                tolerations: typing.Optional[typing.Sequence[typing.Union[Toleration, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument node_selector", value=node_selector, expected_type=type_hints["node_selector"])
            check_type(argname="argument tolerations", value=tolerations, expected_type=type_hints["tolerations"])
        self._values: typing.Dict[str, typing.Any] = {}
        if node_selector is not None:
            self._values["node_selector"] = node_selector
        if tolerations is not None:
            self._values["tolerations"] = tolerations

    @builtins.property
    def node_selector(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''nodeSelector lists labels that must be present on nodes that support this RuntimeClass.

        Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.

        :schema: io.k8s.api.node.v1alpha1.Scheduling#nodeSelector
        '''
        result = self._values.get("node_selector")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def tolerations(self) -> typing.Optional[typing.List["Toleration"]]:
        '''tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.

        :schema: io.k8s.api.node.v1alpha1.Scheduling#tolerations
        '''
        result = self._values.get("tolerations")
        return typing.cast(typing.Optional[typing.List["Toleration"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SchedulingV1Alpha1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SchedulingV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"node_selector": "nodeSelector", "tolerations": "tolerations"},
)
class SchedulingV1Beta1:
    def __init__(
        self,
        *,
        node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        tolerations: typing.Optional[typing.Sequence[typing.Union["Toleration", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.

        :param node_selector: nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.
        :param tolerations: tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.

        :schema: io.k8s.api.node.v1beta1.Scheduling
        '''
        if __debug__:
            def stub(
                *,
                node_selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                tolerations: typing.Optional[typing.Sequence[typing.Union[Toleration, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument node_selector", value=node_selector, expected_type=type_hints["node_selector"])
            check_type(argname="argument tolerations", value=tolerations, expected_type=type_hints["tolerations"])
        self._values: typing.Dict[str, typing.Any] = {}
        if node_selector is not None:
            self._values["node_selector"] = node_selector
        if tolerations is not None:
            self._values["tolerations"] = tolerations

    @builtins.property
    def node_selector(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''nodeSelector lists labels that must be present on nodes that support this RuntimeClass.

        Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.

        :schema: io.k8s.api.node.v1beta1.Scheduling#nodeSelector
        '''
        result = self._values.get("node_selector")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def tolerations(self) -> typing.Optional[typing.List["Toleration"]]:
        '''tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.

        :schema: io.k8s.api.node.v1beta1.Scheduling#tolerations
        '''
        result = self._values.get("tolerations")
        return typing.cast(typing.Optional[typing.List["Toleration"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SchedulingV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ScopeSelector",
    jsii_struct_bases=[],
    name_mapping={"match_expressions": "matchExpressions"},
)
class ScopeSelector:
    def __init__(
        self,
        *,
        match_expressions: typing.Optional[typing.Sequence[typing.Union["ScopedResourceSelectorRequirement", typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''A scope selector represents the AND of the selectors represented by the scoped-resource selector requirements.

        :param match_expressions: A list of scope selector requirements by scope of the resources.

        :schema: io.k8s.api.core.v1.ScopeSelector
        '''
        if __debug__:
            def stub(
                *,
                match_expressions: typing.Optional[typing.Sequence[typing.Union[ScopedResourceSelectorRequirement, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument match_expressions", value=match_expressions, expected_type=type_hints["match_expressions"])
        self._values: typing.Dict[str, typing.Any] = {}
        if match_expressions is not None:
            self._values["match_expressions"] = match_expressions

    @builtins.property
    def match_expressions(
        self,
    ) -> typing.Optional[typing.List["ScopedResourceSelectorRequirement"]]:
        '''A list of scope selector requirements by scope of the resources.

        :schema: io.k8s.api.core.v1.ScopeSelector#matchExpressions
        '''
        result = self._values.get("match_expressions")
        return typing.cast(typing.Optional[typing.List["ScopedResourceSelectorRequirement"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ScopeSelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ScopedResourceSelectorRequirement",
    jsii_struct_bases=[],
    name_mapping={
        "operator": "operator",
        "scope_name": "scopeName",
        "values": "values",
    },
)
class ScopedResourceSelectorRequirement:
    def __init__(
        self,
        *,
        operator: IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator,
        scope_name: IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName,
        values: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''A scoped-resource selector requirement is a selector that contains values, a scope name, and an operator that relates the scope name and values.

        :param operator: Represents a scope's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Possible enum values: - ``"DoesNotExist"`` - ``"Exists"`` - ``"In"`` - ``"NotIn"``
        :param scope_name: The name of the scope that the selector applies to. Possible enum values: - ``"BestEffort"`` Match all pod objects that have best effort quality of service - ``"CrossNamespacePodAffinity"`` Match all pod objects that have cross-namespace pod (anti)affinity mentioned. This is a beta feature enabled by the PodAffinityNamespaceSelector feature flag. - ``"NotBestEffort"`` Match all pod objects that do not have best effort quality of service - ``"NotTerminating"`` Match all pod objects where spec.activeDeadlineSeconds is nil - ``"PriorityClass"`` Match all pod objects that have priority class mentioned - ``"Terminating"`` Match all pod objects where spec.activeDeadlineSeconds >=0
        :param values: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

        :schema: io.k8s.api.core.v1.ScopedResourceSelectorRequirement
        '''
        if __debug__:
            def stub(
                *,
                operator: IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator,
                scope_name: IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName,
                values: typing.Optional[typing.Sequence[builtins.str]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument operator", value=operator, expected_type=type_hints["operator"])
            check_type(argname="argument scope_name", value=scope_name, expected_type=type_hints["scope_name"])
            check_type(argname="argument values", value=values, expected_type=type_hints["values"])
        self._values: typing.Dict[str, typing.Any] = {
            "operator": operator,
            "scope_name": scope_name,
        }
        if values is not None:
            self._values["values"] = values

    @builtins.property
    def operator(self) -> IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator:
        '''Represents a scope's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist.

        Possible enum values:

        - ``"DoesNotExist"``
        - ``"Exists"``
        - ``"In"``
        - ``"NotIn"``

        :schema: io.k8s.api.core.v1.ScopedResourceSelectorRequirement#operator
        '''
        result = self._values.get("operator")
        assert result is not None, "Required property 'operator' is missing"
        return typing.cast(IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator, result)

    @builtins.property
    def scope_name(self) -> IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName:
        '''The name of the scope that the selector applies to.

        Possible enum values:

        - ``"BestEffort"`` Match all pod objects that have best effort quality of service
        - ``"CrossNamespacePodAffinity"`` Match all pod objects that have cross-namespace pod (anti)affinity mentioned. This is a beta feature enabled by the PodAffinityNamespaceSelector feature flag.
        - ``"NotBestEffort"`` Match all pod objects that do not have best effort quality of service
        - ``"NotTerminating"`` Match all pod objects where spec.activeDeadlineSeconds is nil
        - ``"PriorityClass"`` Match all pod objects that have priority class mentioned
        - ``"Terminating"`` Match all pod objects where spec.activeDeadlineSeconds >=0

        :schema: io.k8s.api.core.v1.ScopedResourceSelectorRequirement#scopeName
        '''
        result = self._values.get("scope_name")
        assert result is not None, "Required property 'scope_name' is missing"
        return typing.cast(IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName, result)

    @builtins.property
    def values(self) -> typing.Optional[typing.List[builtins.str]]:
        '''An array of string values.

        If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

        :schema: io.k8s.api.core.v1.ScopedResourceSelectorRequirement#values
        '''
        result = self._values.get("values")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ScopedResourceSelectorRequirement(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SeLinuxOptions",
    jsii_struct_bases=[],
    name_mapping={"level": "level", "role": "role", "type": "type", "user": "user"},
)
class SeLinuxOptions:
    def __init__(
        self,
        *,
        level: typing.Optional[builtins.str] = None,
        role: typing.Optional[builtins.str] = None,
        type: typing.Optional[builtins.str] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''SELinuxOptions are the labels to be applied to the container.

        :param level: Level is SELinux level label that applies to the container.
        :param role: Role is a SELinux role label that applies to the container.
        :param type: Type is a SELinux type label that applies to the container.
        :param user: User is a SELinux user label that applies to the container.

        :schema: io.k8s.api.core.v1.SELinuxOptions
        '''
        if __debug__:
            def stub(
                *,
                level: typing.Optional[builtins.str] = None,
                role: typing.Optional[builtins.str] = None,
                type: typing.Optional[builtins.str] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument level", value=level, expected_type=type_hints["level"])
            check_type(argname="argument role", value=role, expected_type=type_hints["role"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {}
        if level is not None:
            self._values["level"] = level
        if role is not None:
            self._values["role"] = role
        if type is not None:
            self._values["type"] = type
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def level(self) -> typing.Optional[builtins.str]:
        '''Level is SELinux level label that applies to the container.

        :schema: io.k8s.api.core.v1.SELinuxOptions#level
        '''
        result = self._values.get("level")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def role(self) -> typing.Optional[builtins.str]:
        '''Role is a SELinux role label that applies to the container.

        :schema: io.k8s.api.core.v1.SELinuxOptions#role
        '''
        result = self._values.get("role")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''Type is a SELinux type label that applies to the container.

        :schema: io.k8s.api.core.v1.SELinuxOptions#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''User is a SELinux user label that applies to the container.

        :schema: io.k8s.api.core.v1.SELinuxOptions#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SeLinuxOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SeLinuxStrategyOptionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"rule": "rule", "se_linux_options": "seLinuxOptions"},
)
class SeLinuxStrategyOptionsV1Beta1:
    def __init__(
        self,
        *,
        rule: builtins.str,
        se_linux_options: typing.Optional[typing.Union[SeLinuxOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SELinuxStrategyOptions defines the strategy type and any options used to create the strategy.

        :param rule: rule is the strategy that will dictate the allowable labels that may be set.
        :param se_linux_options: seLinuxOptions required to run as; required for MustRunAs More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

        :schema: io.k8s.api.policy.v1beta1.SELinuxStrategyOptions
        '''
        if isinstance(se_linux_options, dict):
            se_linux_options = SeLinuxOptions(**se_linux_options)
        if __debug__:
            def stub(
                *,
                rule: builtins.str,
                se_linux_options: typing.Optional[typing.Union[SeLinuxOptions, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rule", value=rule, expected_type=type_hints["rule"])
            check_type(argname="argument se_linux_options", value=se_linux_options, expected_type=type_hints["se_linux_options"])
        self._values: typing.Dict[str, typing.Any] = {
            "rule": rule,
        }
        if se_linux_options is not None:
            self._values["se_linux_options"] = se_linux_options

    @builtins.property
    def rule(self) -> builtins.str:
        '''rule is the strategy that will dictate the allowable labels that may be set.

        :schema: io.k8s.api.policy.v1beta1.SELinuxStrategyOptions#rule
        '''
        result = self._values.get("rule")
        assert result is not None, "Required property 'rule' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def se_linux_options(self) -> typing.Optional[SeLinuxOptions]:
        '''seLinuxOptions required to run as;

        required for MustRunAs More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

        :schema: io.k8s.api.policy.v1beta1.SELinuxStrategyOptions#seLinuxOptions
        '''
        result = self._values.get("se_linux_options")
        return typing.cast(typing.Optional[SeLinuxOptions], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SeLinuxStrategyOptionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SeccompProfile",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "localhost_profile": "localhostProfile"},
)
class SeccompProfile:
    def __init__(
        self,
        *,
        type: IoK8SApiCoreV1SeccompProfileType,
        localhost_profile: typing.Optional[builtins.str] = None,
    ) -> None:
        '''SeccompProfile defines a pod/container's seccomp profile settings.

        Only one profile source may be set.

        :param type: type indicates which kind of seccomp profile will be applied. Valid options are:. Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. Possible enum values: - ``"Localhost"`` indicates a profile defined in a file on the node should be used. The file's location relative to /seccomp. - ``"RuntimeDefault"`` represents the default container runtime seccomp profile. - ``"Unconfined"`` indicates no seccomp profile is applied (A.K.A. unconfined).
        :param localhost_profile: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost".

        :schema: io.k8s.api.core.v1.SeccompProfile
        '''
        if __debug__:
            def stub(
                *,
                type: IoK8SApiCoreV1SeccompProfileType,
                localhost_profile: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            check_type(argname="argument localhost_profile", value=localhost_profile, expected_type=type_hints["localhost_profile"])
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if localhost_profile is not None:
            self._values["localhost_profile"] = localhost_profile

    @builtins.property
    def type(self) -> IoK8SApiCoreV1SeccompProfileType:
        '''type indicates which kind of seccomp profile will be applied. Valid options are:.

        Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.

        Possible enum values:

        - ``"Localhost"`` indicates a profile defined in a file on the node should be used. The file's location relative to /seccomp.
        - ``"RuntimeDefault"`` represents the default container runtime seccomp profile.
        - ``"Unconfined"`` indicates no seccomp profile is applied (A.K.A. unconfined).

        :schema: io.k8s.api.core.v1.SeccompProfile#type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(IoK8SApiCoreV1SeccompProfileType, result)

    @builtins.property
    def localhost_profile(self) -> typing.Optional[builtins.str]:
        '''localhostProfile indicates a profile defined in a file on the node should be used.

        The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost".

        :schema: io.k8s.api.core.v1.SeccompProfile#localhostProfile
        '''
        result = self._values.get("localhost_profile")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SeccompProfile(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SecretEnvSource",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "optional": "optional"},
)
class SecretEnvSource:
    def __init__(
        self,
        *,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''SecretEnvSource selects a Secret to populate the environment variables with.

        The contents of the target Secret's Data field will represent the key-value pairs as environment variables.

        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the Secret must be defined.

        :schema: io.k8s.api.core.v1.SecretEnvSource
        '''
        if __debug__:
            def stub(
                *,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {}
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.SecretEnvSource#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the Secret must be defined.

        :schema: io.k8s.api.core.v1.SecretEnvSource#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecretEnvSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SecretKeySelector",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "name": "name", "optional": "optional"},
)
class SecretKeySelector:
    def __init__(
        self,
        *,
        key: builtins.str,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''SecretKeySelector selects a key of a Secret.

        :param key: The key of the secret to select from. Must be a valid secret key.
        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the Secret or its key must be defined.

        :schema: io.k8s.api.core.v1.SecretKeySelector
        '''
        if __debug__:
            def stub(
                *,
                key: builtins.str,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {
            "key": key,
        }
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def key(self) -> builtins.str:
        '''The key of the secret to select from.

        Must be a valid secret key.

        :schema: io.k8s.api.core.v1.SecretKeySelector#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.SecretKeySelector#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the Secret or its key must be defined.

        :schema: io.k8s.api.core.v1.SecretKeySelector#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecretKeySelector(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SecretProjection",
    jsii_struct_bases=[],
    name_mapping={"items": "items", "name": "name", "optional": "optional"},
)
class SecretProjection:
    def __init__(
        self,
        *,
        items: typing.Optional[typing.Sequence[typing.Union[KeyToPath, typing.Dict[str, typing.Any]]]] = None,
        name: typing.Optional[builtins.str] = None,
        optional: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Adapts a secret into a projected volume.

        The contents of the target Secret's Data field will be presented in a projected volume as files using the keys in the Data field as the file names. Note that this is identical to a secret volume source without the default mode.

        :param items: If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.
        :param name: Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param optional: Specify whether the Secret or its key must be defined.

        :schema: io.k8s.api.core.v1.SecretProjection
        '''
        if __debug__:
            def stub(
                *,
                items: typing.Optional[typing.Sequence[typing.Union[KeyToPath, typing.Dict[str, typing.Any]]]] = None,
                name: typing.Optional[builtins.str] = None,
                optional: typing.Optional[builtins.bool] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
        self._values: typing.Dict[str, typing.Any] = {}
        if items is not None:
            self._values["items"] = items
        if name is not None:
            self._values["name"] = name
        if optional is not None:
            self._values["optional"] = optional

    @builtins.property
    def items(self) -> typing.Optional[typing.List[KeyToPath]]:
        '''If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value.

        If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.

        :schema: io.k8s.api.core.v1.SecretProjection#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Optional[typing.List[KeyToPath]], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name of the referent.

        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.SecretProjection#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the Secret or its key must be defined.

        :schema: io.k8s.api.core.v1.SecretProjection#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecretProjection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SecretReference",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "namespace": "namespace"},
)
class SecretReference:
    def __init__(
        self,
        *,
        name: typing.Optional[builtins.str] = None,
        namespace: typing.Optional[builtins.str] = None,
    ) -> None:
        '''SecretReference represents a Secret Reference.

        It has enough information to retrieve secret in any namespace

        :param name: Name is unique within a namespace to reference a secret resource.
        :param namespace: Namespace defines the space within which the secret name must be unique.

        :schema: io.k8s.api.core.v1.SecretReference
        '''
        if __debug__:
            def stub(
                *,
                name: typing.Optional[builtins.str] = None,
                namespace: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
        self._values: typing.Dict[str, typing.Any] = {}
        if name is not None:
            self._values["name"] = name
        if namespace is not None:
            self._values["namespace"] = namespace

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name is unique within a namespace to reference a secret resource.

        :schema: io.k8s.api.core.v1.SecretReference#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace defines the space within which the secret name must be unique.

        :schema: io.k8s.api.core.v1.SecretReference#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecretReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SecretVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "default_mode": "defaultMode",
        "items": "items",
        "optional": "optional",
        "secret_name": "secretName",
    },
)
class SecretVolumeSource:
    def __init__(
        self,
        *,
        default_mode: typing.Optional[jsii.Number] = None,
        items: typing.Optional[typing.Sequence[typing.Union[KeyToPath, typing.Dict[str, typing.Any]]]] = None,
        optional: typing.Optional[builtins.bool] = None,
        secret_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Adapts a Secret into a volume.

        The contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.

        :param default_mode: Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. Default: 644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.
        :param items: If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.
        :param optional: Specify whether the Secret or its keys must be defined.
        :param secret_name: Name of the secret in the pod's namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret

        :schema: io.k8s.api.core.v1.SecretVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                default_mode: typing.Optional[jsii.Number] = None,
                items: typing.Optional[typing.Sequence[typing.Union[KeyToPath, typing.Dict[str, typing.Any]]]] = None,
                optional: typing.Optional[builtins.bool] = None,
                secret_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument default_mode", value=default_mode, expected_type=type_hints["default_mode"])
            check_type(argname="argument items", value=items, expected_type=type_hints["items"])
            check_type(argname="argument optional", value=optional, expected_type=type_hints["optional"])
            check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if default_mode is not None:
            self._values["default_mode"] = default_mode
        if items is not None:
            self._values["items"] = items
        if optional is not None:
            self._values["optional"] = optional
        if secret_name is not None:
            self._values["secret_name"] = secret_name

    @builtins.property
    def default_mode(self) -> typing.Optional[jsii.Number]:
        '''Optional: mode bits used to set permissions on created files by default.

        Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :default: 644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

        :schema: io.k8s.api.core.v1.SecretVolumeSource#defaultMode
        '''
        result = self._values.get("default_mode")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def items(self) -> typing.Optional[typing.List[KeyToPath]]:
        '''If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value.

        If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.

        :schema: io.k8s.api.core.v1.SecretVolumeSource#items
        '''
        result = self._values.get("items")
        return typing.cast(typing.Optional[typing.List[KeyToPath]], result)

    @builtins.property
    def optional(self) -> typing.Optional[builtins.bool]:
        '''Specify whether the Secret or its keys must be defined.

        :schema: io.k8s.api.core.v1.SecretVolumeSource#optional
        '''
        result = self._values.get("optional")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_name(self) -> typing.Optional[builtins.str]:
        '''Name of the secret in the pod's namespace to use.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#secret

        :schema: io.k8s.api.core.v1.SecretVolumeSource#secretName
        '''
        result = self._values.get("secret_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecretVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SecurityContext",
    jsii_struct_bases=[],
    name_mapping={
        "allow_privilege_escalation": "allowPrivilegeEscalation",
        "capabilities": "capabilities",
        "privileged": "privileged",
        "proc_mount": "procMount",
        "read_only_root_filesystem": "readOnlyRootFilesystem",
        "run_as_group": "runAsGroup",
        "run_as_non_root": "runAsNonRoot",
        "run_as_user": "runAsUser",
        "seccomp_profile": "seccompProfile",
        "se_linux_options": "seLinuxOptions",
        "windows_options": "windowsOptions",
    },
)
class SecurityContext:
    def __init__(
        self,
        *,
        allow_privilege_escalation: typing.Optional[builtins.bool] = None,
        capabilities: typing.Optional[typing.Union[Capabilities, typing.Dict[str, typing.Any]]] = None,
        privileged: typing.Optional[builtins.bool] = None,
        proc_mount: typing.Optional[builtins.str] = None,
        read_only_root_filesystem: typing.Optional[builtins.bool] = None,
        run_as_group: typing.Optional[jsii.Number] = None,
        run_as_non_root: typing.Optional[builtins.bool] = None,
        run_as_user: typing.Optional[jsii.Number] = None,
        seccomp_profile: typing.Optional[typing.Union[SeccompProfile, typing.Dict[str, typing.Any]]] = None,
        se_linux_options: typing.Optional[typing.Union[SeLinuxOptions, typing.Dict[str, typing.Any]]] = None,
        windows_options: typing.Optional[typing.Union["WindowsSecurityContextOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SecurityContext holds security configuration that will be applied to a container.

        Some fields are present in both SecurityContext and PodSecurityContext.  When both are set, the values in SecurityContext take precedence.

        :param allow_privilege_escalation: AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.
        :param capabilities: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. Default: the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows.
        :param privileged: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. Default: false. Note that this field cannot be set when spec.os.name is windows.
        :param proc_mount: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows.
        :param read_only_root_filesystem: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. Default: false. Note that this field cannot be set when spec.os.name is windows.
        :param run_as_group: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.
        :param run_as_non_root: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.
        :param run_as_user: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. Default: user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.
        :param seccomp_profile: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows.
        :param se_linux_options: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.
        :param windows_options: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux.

        :schema: io.k8s.api.core.v1.SecurityContext
        '''
        if isinstance(capabilities, dict):
            capabilities = Capabilities(**capabilities)
        if isinstance(seccomp_profile, dict):
            seccomp_profile = SeccompProfile(**seccomp_profile)
        if isinstance(se_linux_options, dict):
            se_linux_options = SeLinuxOptions(**se_linux_options)
        if isinstance(windows_options, dict):
            windows_options = WindowsSecurityContextOptions(**windows_options)
        if __debug__:
            def stub(
                *,
                allow_privilege_escalation: typing.Optional[builtins.bool] = None,
                capabilities: typing.Optional[typing.Union[Capabilities, typing.Dict[str, typing.Any]]] = None,
                privileged: typing.Optional[builtins.bool] = None,
                proc_mount: typing.Optional[builtins.str] = None,
                read_only_root_filesystem: typing.Optional[builtins.bool] = None,
                run_as_group: typing.Optional[jsii.Number] = None,
                run_as_non_root: typing.Optional[builtins.bool] = None,
                run_as_user: typing.Optional[jsii.Number] = None,
                seccomp_profile: typing.Optional[typing.Union[SeccompProfile, typing.Dict[str, typing.Any]]] = None,
                se_linux_options: typing.Optional[typing.Union[SeLinuxOptions, typing.Dict[str, typing.Any]]] = None,
                windows_options: typing.Optional[typing.Union[WindowsSecurityContextOptions, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument allow_privilege_escalation", value=allow_privilege_escalation, expected_type=type_hints["allow_privilege_escalation"])
            check_type(argname="argument capabilities", value=capabilities, expected_type=type_hints["capabilities"])
            check_type(argname="argument privileged", value=privileged, expected_type=type_hints["privileged"])
            check_type(argname="argument proc_mount", value=proc_mount, expected_type=type_hints["proc_mount"])
            check_type(argname="argument read_only_root_filesystem", value=read_only_root_filesystem, expected_type=type_hints["read_only_root_filesystem"])
            check_type(argname="argument run_as_group", value=run_as_group, expected_type=type_hints["run_as_group"])
            check_type(argname="argument run_as_non_root", value=run_as_non_root, expected_type=type_hints["run_as_non_root"])
            check_type(argname="argument run_as_user", value=run_as_user, expected_type=type_hints["run_as_user"])
            check_type(argname="argument seccomp_profile", value=seccomp_profile, expected_type=type_hints["seccomp_profile"])
            check_type(argname="argument se_linux_options", value=se_linux_options, expected_type=type_hints["se_linux_options"])
            check_type(argname="argument windows_options", value=windows_options, expected_type=type_hints["windows_options"])
        self._values: typing.Dict[str, typing.Any] = {}
        if allow_privilege_escalation is not None:
            self._values["allow_privilege_escalation"] = allow_privilege_escalation
        if capabilities is not None:
            self._values["capabilities"] = capabilities
        if privileged is not None:
            self._values["privileged"] = privileged
        if proc_mount is not None:
            self._values["proc_mount"] = proc_mount
        if read_only_root_filesystem is not None:
            self._values["read_only_root_filesystem"] = read_only_root_filesystem
        if run_as_group is not None:
            self._values["run_as_group"] = run_as_group
        if run_as_non_root is not None:
            self._values["run_as_non_root"] = run_as_non_root
        if run_as_user is not None:
            self._values["run_as_user"] = run_as_user
        if seccomp_profile is not None:
            self._values["seccomp_profile"] = seccomp_profile
        if se_linux_options is not None:
            self._values["se_linux_options"] = se_linux_options
        if windows_options is not None:
            self._values["windows_options"] = windows_options

    @builtins.property
    def allow_privilege_escalation(self) -> typing.Optional[builtins.bool]:
        '''AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process.

        This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#allowPrivilegeEscalation
        '''
        result = self._values.get("allow_privilege_escalation")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def capabilities(self) -> typing.Optional[Capabilities]:
        '''The capabilities to add/drop when running containers.

        Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows.

        :default: the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#capabilities
        '''
        result = self._values.get("capabilities")
        return typing.cast(typing.Optional[Capabilities], result)

    @builtins.property
    def privileged(self) -> typing.Optional[builtins.bool]:
        '''Run container in privileged mode.

        Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows.

        :default: false. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#privileged
        '''
        result = self._values.get("privileged")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def proc_mount(self) -> typing.Optional[builtins.str]:
        '''procMount denotes the type of proc mount to use for the containers.

        The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#procMount
        '''
        result = self._values.get("proc_mount")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only_root_filesystem(self) -> typing.Optional[builtins.bool]:
        '''Whether this container has a read-only root filesystem.

        Default is false. Note that this field cannot be set when spec.os.name is windows.

        :default: false. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#readOnlyRootFilesystem
        '''
        result = self._values.get("read_only_root_filesystem")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def run_as_group(self) -> typing.Optional[jsii.Number]:
        '''The GID to run the entrypoint of the container process.

        Uses runtime default if unset. May also be set in PodSecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#runAsGroup
        '''
        result = self._values.get("run_as_group")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def run_as_non_root(self) -> typing.Optional[builtins.bool]:
        '''Indicates that the container must run as a non-root user.

        If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.

        :schema: io.k8s.api.core.v1.SecurityContext#runAsNonRoot
        '''
        result = self._values.get("run_as_non_root")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def run_as_user(self) -> typing.Optional[jsii.Number]:
        '''The UID to run the entrypoint of the container process.

        Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.

        :default: user specified in image metadata if unspecified. May also be set in PodSecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#runAsUser
        '''
        result = self._values.get("run_as_user")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def seccomp_profile(self) -> typing.Optional[SeccompProfile]:
        '''The seccomp options to use by this container.

        If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#seccompProfile
        '''
        result = self._values.get("seccomp_profile")
        return typing.cast(typing.Optional[SeccompProfile], result)

    @builtins.property
    def se_linux_options(self) -> typing.Optional[SeLinuxOptions]:
        '''The SELinux context to be applied to the container.

        If unspecified, the container runtime will allocate a random SELinux context for each container.  May also be set in PodSecurityContext.  If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows.

        :schema: io.k8s.api.core.v1.SecurityContext#seLinuxOptions
        '''
        result = self._values.get("se_linux_options")
        return typing.cast(typing.Optional[SeLinuxOptions], result)

    @builtins.property
    def windows_options(self) -> typing.Optional["WindowsSecurityContextOptions"]:
        '''The Windows specific settings applied to all containers.

        If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux.

        :schema: io.k8s.api.core.v1.SecurityContext#windowsOptions
        '''
        result = self._values.get("windows_options")
        return typing.cast(typing.Optional["WindowsSecurityContextOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecurityContext(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SelfSubjectAccessReviewSpec",
    jsii_struct_bases=[],
    name_mapping={
        "non_resource_attributes": "nonResourceAttributes",
        "resource_attributes": "resourceAttributes",
    },
)
class SelfSubjectAccessReviewSpec:
    def __init__(
        self,
        *,
        non_resource_attributes: typing.Optional[typing.Union[NonResourceAttributes, typing.Dict[str, typing.Any]]] = None,
        resource_attributes: typing.Optional[typing.Union[ResourceAttributes, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SelfSubjectAccessReviewSpec is a description of the access request.

        Exactly one of ResourceAuthorizationAttributes and NonResourceAuthorizationAttributes must be set

        :param non_resource_attributes: NonResourceAttributes describes information for a non-resource access request.
        :param resource_attributes: ResourceAuthorizationAttributes describes information for a resource access request.

        :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReviewSpec
        '''
        if isinstance(non_resource_attributes, dict):
            non_resource_attributes = NonResourceAttributes(**non_resource_attributes)
        if isinstance(resource_attributes, dict):
            resource_attributes = ResourceAttributes(**resource_attributes)
        if __debug__:
            def stub(
                *,
                non_resource_attributes: typing.Optional[typing.Union[NonResourceAttributes, typing.Dict[str, typing.Any]]] = None,
                resource_attributes: typing.Optional[typing.Union[ResourceAttributes, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument non_resource_attributes", value=non_resource_attributes, expected_type=type_hints["non_resource_attributes"])
            check_type(argname="argument resource_attributes", value=resource_attributes, expected_type=type_hints["resource_attributes"])
        self._values: typing.Dict[str, typing.Any] = {}
        if non_resource_attributes is not None:
            self._values["non_resource_attributes"] = non_resource_attributes
        if resource_attributes is not None:
            self._values["resource_attributes"] = resource_attributes

    @builtins.property
    def non_resource_attributes(self) -> typing.Optional[NonResourceAttributes]:
        '''NonResourceAttributes describes information for a non-resource access request.

        :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReviewSpec#nonResourceAttributes
        '''
        result = self._values.get("non_resource_attributes")
        return typing.cast(typing.Optional[NonResourceAttributes], result)

    @builtins.property
    def resource_attributes(self) -> typing.Optional[ResourceAttributes]:
        '''ResourceAuthorizationAttributes describes information for a resource access request.

        :schema: io.k8s.api.authorization.v1.SelfSubjectAccessReviewSpec#resourceAttributes
        '''
        result = self._values.get("resource_attributes")
        return typing.cast(typing.Optional[ResourceAttributes], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SelfSubjectAccessReviewSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SelfSubjectRulesReviewSpec",
    jsii_struct_bases=[],
    name_mapping={"namespace": "namespace"},
)
class SelfSubjectRulesReviewSpec:
    def __init__(self, *, namespace: typing.Optional[builtins.str] = None) -> None:
        '''SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview.

        :param namespace: Namespace to evaluate rules for. Required.

        :schema: io.k8s.api.authorization.v1.SelfSubjectRulesReviewSpec
        '''
        if __debug__:
            def stub(*, namespace: typing.Optional[builtins.str] = None) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
        self._values: typing.Dict[str, typing.Any] = {}
        if namespace is not None:
            self._values["namespace"] = namespace

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace to evaluate rules for.

        Required.

        :schema: io.k8s.api.authorization.v1.SelfSubjectRulesReviewSpec#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SelfSubjectRulesReviewSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServiceAccountSubjectV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "namespace": "namespace"},
)
class ServiceAccountSubjectV1Beta1:
    def __init__(self, *, name: builtins.str, namespace: builtins.str) -> None:
        '''ServiceAccountSubject holds detailed information for service-account-kind subject.

        :param name: ``name`` is the name of matching ServiceAccount objects, or "*" to match regardless of name. Required.
        :param namespace: ``namespace`` is the namespace of matching ServiceAccount objects. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject
        '''
        if __debug__:
            def stub(*, name: builtins.str, namespace: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "namespace": namespace,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the name of matching ServiceAccount objects, or "*" to match regardless of name.

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def namespace(self) -> builtins.str:
        '''``namespace`` is the namespace of matching ServiceAccount objects.

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject#namespace
        '''
        result = self._values.get("namespace")
        assert result is not None, "Required property 'namespace' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceAccountSubjectV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServiceAccountSubjectV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "namespace": "namespace"},
)
class ServiceAccountSubjectV1Beta2:
    def __init__(self, *, name: builtins.str, namespace: builtins.str) -> None:
        '''ServiceAccountSubject holds detailed information for service-account-kind subject.

        :param name: ``name`` is the name of matching ServiceAccount objects, or "*" to match regardless of name. Required.
        :param namespace: ``namespace`` is the namespace of matching ServiceAccount objects. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject
        '''
        if __debug__:
            def stub(*, name: builtins.str, namespace: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "namespace": namespace,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the name of matching ServiceAccount objects, or "*" to match regardless of name.

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def namespace(self) -> builtins.str:
        '''``namespace`` is the namespace of matching ServiceAccount objects.

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject#namespace
        '''
        result = self._values.get("namespace")
        assert result is not None, "Required property 'namespace' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceAccountSubjectV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServiceAccountTokenProjection",
    jsii_struct_bases=[],
    name_mapping={
        "path": "path",
        "audience": "audience",
        "expiration_seconds": "expirationSeconds",
    },
)
class ServiceAccountTokenProjection:
    def __init__(
        self,
        *,
        path: builtins.str,
        audience: typing.Optional[builtins.str] = None,
        expiration_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''ServiceAccountTokenProjection represents a projected service account token volume.

        This projection can be used to insert a service account token into the pods runtime filesystem for use against APIs (Kubernetes API Server or otherwise).

        :param path: Path is the path relative to the mount point of the file to project the token into.
        :param audience: Audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver.
        :param expiration_seconds: ExpirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes. Default: 1 hour and must be at least 10 minutes.

        :schema: io.k8s.api.core.v1.ServiceAccountTokenProjection
        '''
        if __debug__:
            def stub(
                *,
                path: builtins.str,
                audience: typing.Optional[builtins.str] = None,
                expiration_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument audience", value=audience, expected_type=type_hints["audience"])
            check_type(argname="argument expiration_seconds", value=expiration_seconds, expected_type=type_hints["expiration_seconds"])
        self._values: typing.Dict[str, typing.Any] = {
            "path": path,
        }
        if audience is not None:
            self._values["audience"] = audience
        if expiration_seconds is not None:
            self._values["expiration_seconds"] = expiration_seconds

    @builtins.property
    def path(self) -> builtins.str:
        '''Path is the path relative to the mount point of the file to project the token into.

        :schema: io.k8s.api.core.v1.ServiceAccountTokenProjection#path
        '''
        result = self._values.get("path")
        assert result is not None, "Required property 'path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def audience(self) -> typing.Optional[builtins.str]:
        '''Audience is the intended audience of the token.

        A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver.

        :schema: io.k8s.api.core.v1.ServiceAccountTokenProjection#audience
        '''
        result = self._values.get("audience")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def expiration_seconds(self) -> typing.Optional[jsii.Number]:
        '''ExpirationSeconds is the requested duration of validity of the service account token.

        As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes.

        :default: 1 hour and must be at least 10 minutes.

        :schema: io.k8s.api.core.v1.ServiceAccountTokenProjection#expirationSeconds
        '''
        result = self._values.get("expiration_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceAccountTokenProjection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServiceBackendPort",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "number": "number"},
)
class ServiceBackendPort:
    def __init__(
        self,
        *,
        name: typing.Optional[builtins.str] = None,
        number: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''ServiceBackendPort is the service port being referenced.

        :param name: Name is the name of the port on the Service. This is a mutually exclusive setting with "Number".
        :param number: Number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name".

        :schema: io.k8s.api.networking.v1.ServiceBackendPort
        '''
        if __debug__:
            def stub(
                *,
                name: typing.Optional[builtins.str] = None,
                number: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument number", value=number, expected_type=type_hints["number"])
        self._values: typing.Dict[str, typing.Any] = {}
        if name is not None:
            self._values["name"] = name
        if number is not None:
            self._values["number"] = number

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''Name is the name of the port on the Service.

        This is a mutually exclusive setting with "Number".

        :schema: io.k8s.api.networking.v1.ServiceBackendPort#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def number(self) -> typing.Optional[jsii.Number]:
        '''Number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name".

        :schema: io.k8s.api.networking.v1.ServiceBackendPort#number
        '''
        result = self._values.get("number")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceBackendPort(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServicePort",
    jsii_struct_bases=[],
    name_mapping={
        "port": "port",
        "app_protocol": "appProtocol",
        "name": "name",
        "node_port": "nodePort",
        "protocol": "protocol",
        "target_port": "targetPort",
    },
)
class ServicePort:
    def __init__(
        self,
        *,
        port: jsii.Number,
        app_protocol: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        node_port: typing.Optional[jsii.Number] = None,
        protocol: typing.Optional[IoK8SApiCoreV1ServicePortProtocol] = None,
        target_port: typing.Optional[IntOrString] = None,
    ) -> None:
        '''ServicePort contains information on service's port.

        :param port: The port that will be exposed by this service.
        :param app_protocol: The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.
        :param name: The name of this port within the service. This must be a DNS_LABEL. All ports within a ServiceSpec must have unique names. When considering the endpoints for a Service, this must match the 'name' field in the EndpointPort. Optional if only one ServicePort is defined on this service.
        :param node_port: The port on each node on which this service is exposed when type is NodePort or LoadBalancer. Usually assigned by the system. If a value is specified, in-range, and not in use it will be used, otherwise the operation will fail. If not specified, a port will be allocated if this Service requires one. If this field is specified when creating a Service which does not need it, creation will fail. This field will be wiped when updating a Service to no longer need it (e.g. changing type from NodePort to ClusterIP). More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
        :param protocol: The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". Default is TCP. Possible enum values: - ``"SCTP"`` is the SCTP protocol. - ``"TCP"`` is the TCP protocol. - ``"UDP"`` is the UDP protocol. Default: TCP.
        :param target_port: Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service

        :schema: io.k8s.api.core.v1.ServicePort
        '''
        if __debug__:
            def stub(
                *,
                port: jsii.Number,
                app_protocol: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                node_port: typing.Optional[jsii.Number] = None,
                protocol: typing.Optional[IoK8SApiCoreV1ServicePortProtocol] = None,
                target_port: typing.Optional[IntOrString] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument app_protocol", value=app_protocol, expected_type=type_hints["app_protocol"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument node_port", value=node_port, expected_type=type_hints["node_port"])
            check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
            check_type(argname="argument target_port", value=target_port, expected_type=type_hints["target_port"])
        self._values: typing.Dict[str, typing.Any] = {
            "port": port,
        }
        if app_protocol is not None:
            self._values["app_protocol"] = app_protocol
        if name is not None:
            self._values["name"] = name
        if node_port is not None:
            self._values["node_port"] = node_port
        if protocol is not None:
            self._values["protocol"] = protocol
        if target_port is not None:
            self._values["target_port"] = target_port

    @builtins.property
    def port(self) -> jsii.Number:
        '''The port that will be exposed by this service.

        :schema: io.k8s.api.core.v1.ServicePort#port
        '''
        result = self._values.get("port")
        assert result is not None, "Required property 'port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def app_protocol(self) -> typing.Optional[builtins.str]:
        '''The application protocol for this port.

        This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.

        :schema: io.k8s.api.core.v1.ServicePort#appProtocol
        '''
        result = self._values.get("app_protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''The name of this port within the service.

        This must be a DNS_LABEL. All ports within a ServiceSpec must have unique names. When considering the endpoints for a Service, this must match the 'name' field in the EndpointPort. Optional if only one ServicePort is defined on this service.

        :schema: io.k8s.api.core.v1.ServicePort#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_port(self) -> typing.Optional[jsii.Number]:
        '''The port on each node on which this service is exposed when type is NodePort or LoadBalancer.

        Usually assigned by the system. If a value is specified, in-range, and not in use it will be used, otherwise the operation will fail.  If not specified, a port will be allocated if this Service requires one.  If this field is specified when creating a Service which does not need it, creation will fail. This field will be wiped when updating a Service to no longer need it (e.g. changing type from NodePort to ClusterIP). More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport

        :schema: io.k8s.api.core.v1.ServicePort#nodePort
        '''
        result = self._values.get("node_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def protocol(self) -> typing.Optional[IoK8SApiCoreV1ServicePortProtocol]:
        '''The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". Default is TCP.

        Possible enum values:

        - ``"SCTP"`` is the SCTP protocol.
        - ``"TCP"`` is the TCP protocol.
        - ``"UDP"`` is the UDP protocol.

        :default: TCP.

        :schema: io.k8s.api.core.v1.ServicePort#protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional[IoK8SApiCoreV1ServicePortProtocol], result)

    @builtins.property
    def target_port(self) -> typing.Optional[IntOrString]:
        '''Number or name of the port to access on the pods targeted by the service.

        Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service

        :schema: io.k8s.api.core.v1.ServicePort#targetPort
        '''
        result = self._values.get("target_port")
        return typing.cast(typing.Optional[IntOrString], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServicePort(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServiceReference",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "namespace": "namespace",
        "path": "path",
        "port": "port",
    },
)
class ServiceReference:
    def __init__(
        self,
        *,
        name: builtins.str,
        namespace: builtins.str,
        path: typing.Optional[builtins.str] = None,
        port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''ServiceReference holds a reference to Service.legacy.k8s.io.

        :param name: ``name`` is the name of the service. Required
        :param namespace: ``namespace`` is the namespace of the service. Required
        :param path: ``path`` is an optional URL path which will be sent in any request to this service.
        :param port: If specified, the port on the service that hosting webhook. Default to 443 for backward compatibility. ``port`` should be a valid port number (1-65535, inclusive). Default: 443 for backward compatibility. ``port`` should be a valid port number (1-65535, inclusive).

        :schema: io.k8s.api.admissionregistration.v1.ServiceReference
        '''
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                namespace: builtins.str,
                path: typing.Optional[builtins.str] = None,
                port: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "namespace": namespace,
        }
        if path is not None:
            self._values["path"] = path
        if port is not None:
            self._values["port"] = port

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the name of the service.

        Required

        :schema: io.k8s.api.admissionregistration.v1.ServiceReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def namespace(self) -> builtins.str:
        '''``namespace`` is the namespace of the service.

        Required

        :schema: io.k8s.api.admissionregistration.v1.ServiceReference#namespace
        '''
        result = self._values.get("namespace")
        assert result is not None, "Required property 'namespace' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''``path`` is an optional URL path which will be sent in any request to this service.

        :schema: io.k8s.api.admissionregistration.v1.ServiceReference#path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''If specified, the port on the service that hosting webhook.

        Default to 443 for backward compatibility. ``port`` should be a valid port number (1-65535, inclusive).

        :default: 443 for backward compatibility. ``port`` should be a valid port number (1-65535, inclusive).

        :schema: io.k8s.api.admissionregistration.v1.ServiceReference#port
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ServiceSpec",
    jsii_struct_bases=[],
    name_mapping={
        "allocate_load_balancer_node_ports": "allocateLoadBalancerNodePorts",
        "cluster_ip": "clusterIp",
        "cluster_i_ps": "clusterIPs",
        "external_i_ps": "externalIPs",
        "external_name": "externalName",
        "external_traffic_policy": "externalTrafficPolicy",
        "health_check_node_port": "healthCheckNodePort",
        "internal_traffic_policy": "internalTrafficPolicy",
        "ip_families": "ipFamilies",
        "ip_family_policy": "ipFamilyPolicy",
        "load_balancer_class": "loadBalancerClass",
        "load_balancer_ip": "loadBalancerIp",
        "load_balancer_source_ranges": "loadBalancerSourceRanges",
        "ports": "ports",
        "publish_not_ready_addresses": "publishNotReadyAddresses",
        "selector": "selector",
        "session_affinity": "sessionAffinity",
        "session_affinity_config": "sessionAffinityConfig",
        "type": "type",
    },
)
class ServiceSpec:
    def __init__(
        self,
        *,
        allocate_load_balancer_node_ports: typing.Optional[builtins.bool] = None,
        cluster_ip: typing.Optional[builtins.str] = None,
        cluster_i_ps: typing.Optional[typing.Sequence[builtins.str]] = None,
        external_i_ps: typing.Optional[typing.Sequence[builtins.str]] = None,
        external_name: typing.Optional[builtins.str] = None,
        external_traffic_policy: typing.Optional[IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy] = None,
        health_check_node_port: typing.Optional[jsii.Number] = None,
        internal_traffic_policy: typing.Optional[builtins.str] = None,
        ip_families: typing.Optional[typing.Sequence[builtins.str]] = None,
        ip_family_policy: typing.Optional[builtins.str] = None,
        load_balancer_class: typing.Optional[builtins.str] = None,
        load_balancer_ip: typing.Optional[builtins.str] = None,
        load_balancer_source_ranges: typing.Optional[typing.Sequence[builtins.str]] = None,
        ports: typing.Optional[typing.Sequence[typing.Union[ServicePort, typing.Dict[str, typing.Any]]]] = None,
        publish_not_ready_addresses: typing.Optional[builtins.bool] = None,
        selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        session_affinity: typing.Optional[IoK8SApiCoreV1ServiceSpecSessionAffinity] = None,
        session_affinity_config: typing.Optional[typing.Union["SessionAffinityConfig", typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[IoK8SApiCoreV1ServiceSpecType] = None,
    ) -> None:
        '''ServiceSpec describes the attributes that a user creates on a service.

        :param allocate_load_balancer_node_ports: allocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer. Default is "true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature. Default: true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature.
        :param cluster_ip: clusterIP is the IP address of the service and is usually assigned randomly. If an address is specified manually, is in-range (as per system configuration), and is not in use, it will be allocated to the service; otherwise creation of the service will fail. This field may not be changed through updates unless the type field is also being changed to ExternalName (which requires this field to be blank) or the type field is being changed from ExternalName (in which case this field may optionally be specified, as describe above). Valid values are "None", empty string (""), or a valid IP address. Setting this to "None" makes a "headless service" (no virtual IP), which is useful when direct endpoint connections are preferred and proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. If this field is specified when creating a Service of type ExternalName, creation will fail. This field will be wiped when updating a Service to type ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
        :param cluster_i_ps: ClusterIPs is a list of IP addresses assigned to this service, and are usually assigned randomly. If an address is specified manually, is in-range (as per system configuration), and is not in use, it will be allocated to the service; otherwise creation of the service will fail. This field may not be changed through updates unless the type field is also being changed to ExternalName (which requires this field to be empty) or the type field is being changed from ExternalName (in which case this field may optionally be specified, as describe above). Valid values are "None", empty string (""), or a valid IP address. Setting this to "None" makes a "headless service" (no virtual IP), which is useful when direct endpoint connections are preferred and proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. If this field is specified when creating a Service of type ExternalName, creation will fail. This field will be wiped when updating a Service to type ExternalName. If this field is not specified, it will be initialized from the clusterIP field. If this field is specified, clients must ensure that clusterIPs[0] and clusterIP have the same value. This field may hold a maximum of two entries (dual-stack IPs, in either order). These IPs must correspond to the values of the ipFamilies field. Both clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
        :param external_i_ps: externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system.
        :param external_name: externalName is the external reference that discovery mechanisms will return as an alias for this service (e.g. a DNS CNAME record). No proxying will be involved. Must be a lowercase RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) and requires ``type`` to be "ExternalName".
        :param external_traffic_policy: externalTrafficPolicy denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints. "Local" preserves the client source IP and avoids a second hop for LoadBalancer and Nodeport type services, but risks potentially imbalanced traffic spreading. "Cluster" obscures the client source IP and may cause a second hop to another node, but should have good overall load-spreading. Possible enum values: - ``"Cluster"`` specifies node-global (legacy) behavior. - ``"Local"`` specifies node-local endpoints behavior.
        :param health_check_node_port: healthCheckNodePort specifies the healthcheck nodePort for the service. This only applies when type is set to LoadBalancer and externalTrafficPolicy is set to Local. If a value is specified, is in-range, and is not in use, it will be used. If not specified, a value will be automatically allocated. External systems (e.g. load-balancers) can use this port to determine if a given node holds endpoints for this service or not. If this field is specified when creating a Service which does not need it, creation will fail. This field will be wiped when updating a Service to no longer need it (e.g. changing type).
        :param internal_traffic_policy: InternalTrafficPolicy specifies if the cluster internal traffic should be routed to all endpoints or node-local endpoints only. "Cluster" routes internal traffic to a Service to all endpoints. "Local" routes traffic to node-local endpoints only, traffic is dropped if no node-local endpoints are ready. The default value is "Cluster".
        :param ip_families: IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this service. This field is usually assigned automatically based on cluster configuration and the ipFamilyPolicy field. If this field is specified manually, the requested family is available in the cluster, and ipFamilyPolicy allows it, it will be used; otherwise creation of the service will fail. This field is conditionally mutable: it allows for adding or removing a secondary IP family, but it does not allow changing the primary IP family of the Service. Valid values are "IPv4" and "IPv6". This field only applies to Services of types ClusterIP, NodePort, and LoadBalancer, and does apply to "headless" services. This field will be wiped when updating a Service to type ExternalName. This field may hold a maximum of two entries (dual-stack families, in either order). These families must correspond to the values of the clusterIPs field, if specified. Both clusterIPs and ipFamilies are governed by the ipFamilyPolicy field.
        :param ip_family_policy: IPFamilyPolicy represents the dual-stack-ness requested or required by this Service. If there is no value provided, then this field will be set to SingleStack. Services can be "SingleStack" (a single IP family), "PreferDualStack" (two IP families on dual-stack configured clusters or a single IP family on single-stack clusters), or "RequireDualStack" (two IP families on dual-stack configured clusters, otherwise fail). The ipFamilies and clusterIPs fields depend on the value of this field. This field will be wiped when updating a service to type ExternalName.
        :param load_balancer_class: loadBalancerClass is the class of the load balancer implementation this Service belongs to. If specified, the value of this field must be a label-style identifier, with an optional prefix, e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load balancer implementation is used, today this is typically done through the cloud provider integration, but should apply for any default implementation. If set, it is assumed that a load balancer implementation is watching for Services with a matching class. Any default load balancer implementation (e.g. cloud providers) should ignore Services that set this field. This field can only be set when creating or updating a Service to type 'LoadBalancer'. Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type.
        :param load_balancer_ip: Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.
        :param load_balancer_source_ranges: If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
        :param ports: The list of ports that are exposed by this service. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
        :param publish_not_ready_addresses: publishNotReadyAddresses indicates that any agent which deals with endpoints for this Service should disregard any indications of ready/not-ready. The primary use case for setting this field is for a StatefulSet's Headless Service to propagate SRV DNS records for its Pods for the purpose of peer discovery. The Kubernetes controllers that generate Endpoints and EndpointSlice resources for Services interpret this to mean that all endpoints are considered "ready" even if the Pods themselves are not. Agents which consume only Kubernetes generated endpoints through the Endpoints or EndpointSlice resources can safely assume this behavior.
        :param selector: Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/
        :param session_affinity: Supports "ClientIP" and "None". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies Possible enum values: - ``"ClientIP"`` is the Client IP based. - ``"None"`` - no session affinity. Default: None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
        :param session_affinity_config: sessionAffinityConfig contains the configurations of session affinity.
        :param type: type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object or EndpointSlice objects. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a virtual IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the same endpoints as the clusterIP. "ExternalName" aliases this service to the specified externalName. Several other fields do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types Possible enum values: - ``"ClusterIP"`` means a service will only be accessible inside the cluster, via the cluster IP. - ``"ExternalName"`` means a service consists of only a reference to an external name that kubedns or equivalent will return as a CNAME record, with no exposing or proxying of any pods involved. - ``"LoadBalancer"`` means a service will be exposed via an external load balancer (if the cloud provider supports it), in addition to 'NodePort' type. - ``"NodePort"`` means a service will be exposed on one port of every node, in addition to 'ClusterIP' type. Default: ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object or EndpointSlice objects. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a virtual IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the same endpoints as the clusterIP. "ExternalName" aliases this service to the specified externalName. Several other fields do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

        :schema: io.k8s.api.core.v1.ServiceSpec
        '''
        if isinstance(session_affinity_config, dict):
            session_affinity_config = SessionAffinityConfig(**session_affinity_config)
        if __debug__:
            def stub(
                *,
                allocate_load_balancer_node_ports: typing.Optional[builtins.bool] = None,
                cluster_ip: typing.Optional[builtins.str] = None,
                cluster_i_ps: typing.Optional[typing.Sequence[builtins.str]] = None,
                external_i_ps: typing.Optional[typing.Sequence[builtins.str]] = None,
                external_name: typing.Optional[builtins.str] = None,
                external_traffic_policy: typing.Optional[IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy] = None,
                health_check_node_port: typing.Optional[jsii.Number] = None,
                internal_traffic_policy: typing.Optional[builtins.str] = None,
                ip_families: typing.Optional[typing.Sequence[builtins.str]] = None,
                ip_family_policy: typing.Optional[builtins.str] = None,
                load_balancer_class: typing.Optional[builtins.str] = None,
                load_balancer_ip: typing.Optional[builtins.str] = None,
                load_balancer_source_ranges: typing.Optional[typing.Sequence[builtins.str]] = None,
                ports: typing.Optional[typing.Sequence[typing.Union[ServicePort, typing.Dict[str, typing.Any]]]] = None,
                publish_not_ready_addresses: typing.Optional[builtins.bool] = None,
                selector: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
                session_affinity: typing.Optional[IoK8SApiCoreV1ServiceSpecSessionAffinity] = None,
                session_affinity_config: typing.Optional[typing.Union[SessionAffinityConfig, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[IoK8SApiCoreV1ServiceSpecType] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument allocate_load_balancer_node_ports", value=allocate_load_balancer_node_ports, expected_type=type_hints["allocate_load_balancer_node_ports"])
            check_type(argname="argument cluster_ip", value=cluster_ip, expected_type=type_hints["cluster_ip"])
            check_type(argname="argument cluster_i_ps", value=cluster_i_ps, expected_type=type_hints["cluster_i_ps"])
            check_type(argname="argument external_i_ps", value=external_i_ps, expected_type=type_hints["external_i_ps"])
            check_type(argname="argument external_name", value=external_name, expected_type=type_hints["external_name"])
            check_type(argname="argument external_traffic_policy", value=external_traffic_policy, expected_type=type_hints["external_traffic_policy"])
            check_type(argname="argument health_check_node_port", value=health_check_node_port, expected_type=type_hints["health_check_node_port"])
            check_type(argname="argument internal_traffic_policy", value=internal_traffic_policy, expected_type=type_hints["internal_traffic_policy"])
            check_type(argname="argument ip_families", value=ip_families, expected_type=type_hints["ip_families"])
            check_type(argname="argument ip_family_policy", value=ip_family_policy, expected_type=type_hints["ip_family_policy"])
            check_type(argname="argument load_balancer_class", value=load_balancer_class, expected_type=type_hints["load_balancer_class"])
            check_type(argname="argument load_balancer_ip", value=load_balancer_ip, expected_type=type_hints["load_balancer_ip"])
            check_type(argname="argument load_balancer_source_ranges", value=load_balancer_source_ranges, expected_type=type_hints["load_balancer_source_ranges"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
            check_type(argname="argument publish_not_ready_addresses", value=publish_not_ready_addresses, expected_type=type_hints["publish_not_ready_addresses"])
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument session_affinity", value=session_affinity, expected_type=type_hints["session_affinity"])
            check_type(argname="argument session_affinity_config", value=session_affinity_config, expected_type=type_hints["session_affinity_config"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {}
        if allocate_load_balancer_node_ports is not None:
            self._values["allocate_load_balancer_node_ports"] = allocate_load_balancer_node_ports
        if cluster_ip is not None:
            self._values["cluster_ip"] = cluster_ip
        if cluster_i_ps is not None:
            self._values["cluster_i_ps"] = cluster_i_ps
        if external_i_ps is not None:
            self._values["external_i_ps"] = external_i_ps
        if external_name is not None:
            self._values["external_name"] = external_name
        if external_traffic_policy is not None:
            self._values["external_traffic_policy"] = external_traffic_policy
        if health_check_node_port is not None:
            self._values["health_check_node_port"] = health_check_node_port
        if internal_traffic_policy is not None:
            self._values["internal_traffic_policy"] = internal_traffic_policy
        if ip_families is not None:
            self._values["ip_families"] = ip_families
        if ip_family_policy is not None:
            self._values["ip_family_policy"] = ip_family_policy
        if load_balancer_class is not None:
            self._values["load_balancer_class"] = load_balancer_class
        if load_balancer_ip is not None:
            self._values["load_balancer_ip"] = load_balancer_ip
        if load_balancer_source_ranges is not None:
            self._values["load_balancer_source_ranges"] = load_balancer_source_ranges
        if ports is not None:
            self._values["ports"] = ports
        if publish_not_ready_addresses is not None:
            self._values["publish_not_ready_addresses"] = publish_not_ready_addresses
        if selector is not None:
            self._values["selector"] = selector
        if session_affinity is not None:
            self._values["session_affinity"] = session_affinity
        if session_affinity_config is not None:
            self._values["session_affinity_config"] = session_affinity_config
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def allocate_load_balancer_node_ports(self) -> typing.Optional[builtins.bool]:
        '''allocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer.

        Default is "true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts.  If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature.

        :default: true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts.  If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature.

        :schema: io.k8s.api.core.v1.ServiceSpec#allocateLoadBalancerNodePorts
        '''
        result = self._values.get("allocate_load_balancer_node_ports")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def cluster_ip(self) -> typing.Optional[builtins.str]:
        '''clusterIP is the IP address of the service and is usually assigned randomly.

        If an address is specified manually, is in-range (as per system configuration), and is not in use, it will be allocated to the service; otherwise creation of the service will fail. This field may not be changed through updates unless the type field is also being changed to ExternalName (which requires this field to be blank) or the type field is being changed from ExternalName (in which case this field may optionally be specified, as describe above).  Valid values are "None", empty string (""), or a valid IP address. Setting this to "None" makes a "headless service" (no virtual IP), which is useful when direct endpoint connections are preferred and proxying is not required.  Only applies to types ClusterIP, NodePort, and LoadBalancer. If this field is specified when creating a Service of type ExternalName, creation will fail. This field will be wiped when updating a Service to type ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

        :schema: io.k8s.api.core.v1.ServiceSpec#clusterIP
        '''
        result = self._values.get("cluster_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cluster_i_ps(self) -> typing.Optional[typing.List[builtins.str]]:
        '''ClusterIPs is a list of IP addresses assigned to this service, and are usually assigned randomly.

        If an address is specified manually, is in-range (as per system configuration), and is not in use, it will be allocated to the service; otherwise creation of the service will fail. This field may not be changed through updates unless the type field is also being changed to ExternalName (which requires this field to be empty) or the type field is being changed from ExternalName (in which case this field may optionally be specified, as describe above).  Valid values are "None", empty string (""), or a valid IP address.  Setting this to "None" makes a "headless service" (no virtual IP), which is useful when direct endpoint connections are preferred and proxying is not required.  Only applies to types ClusterIP, NodePort, and LoadBalancer. If this field is specified when creating a Service of type ExternalName, creation will fail. This field will be wiped when updating a Service to type ExternalName.  If this field is not specified, it will be initialized from the clusterIP field.  If this field is specified, clients must ensure that clusterIPs[0] and clusterIP have the same value.

        This field may hold a maximum of two entries (dual-stack IPs, in either order). These IPs must correspond to the values of the ipFamilies field. Both clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

        :schema: io.k8s.api.core.v1.ServiceSpec#clusterIPs
        '''
        result = self._values.get("cluster_i_ps")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def external_i_ps(self) -> typing.Optional[typing.List[builtins.str]]:
        '''externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service.

        These IPs are not managed by Kubernetes.  The user is responsible for ensuring that traffic arrives at a node with this IP.  A common example is external load-balancers that are not part of the Kubernetes system.

        :schema: io.k8s.api.core.v1.ServiceSpec#externalIPs
        '''
        result = self._values.get("external_i_ps")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def external_name(self) -> typing.Optional[builtins.str]:
        '''externalName is the external reference that discovery mechanisms will return as an alias for this service (e.g. a DNS CNAME record). No proxying will be involved.  Must be a lowercase RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) and requires ``type`` to be "ExternalName".

        :schema: io.k8s.api.core.v1.ServiceSpec#externalName
        '''
        result = self._values.get("external_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def external_traffic_policy(
        self,
    ) -> typing.Optional[IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy]:
        '''externalTrafficPolicy denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints.

        "Local" preserves the client source IP and avoids a second hop for LoadBalancer and Nodeport type services, but risks potentially imbalanced traffic spreading. "Cluster" obscures the client source IP and may cause a second hop to another node, but should have good overall load-spreading.

        Possible enum values:

        - ``"Cluster"`` specifies node-global (legacy) behavior.
        - ``"Local"`` specifies node-local endpoints behavior.

        :schema: io.k8s.api.core.v1.ServiceSpec#externalTrafficPolicy
        '''
        result = self._values.get("external_traffic_policy")
        return typing.cast(typing.Optional[IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy], result)

    @builtins.property
    def health_check_node_port(self) -> typing.Optional[jsii.Number]:
        '''healthCheckNodePort specifies the healthcheck nodePort for the service.

        This only applies when type is set to LoadBalancer and externalTrafficPolicy is set to Local. If a value is specified, is in-range, and is not in use, it will be used.  If not specified, a value will be automatically allocated.  External systems (e.g. load-balancers) can use this port to determine if a given node holds endpoints for this service or not.  If this field is specified when creating a Service which does not need it, creation will fail. This field will be wiped when updating a Service to no longer need it (e.g. changing type).

        :schema: io.k8s.api.core.v1.ServiceSpec#healthCheckNodePort
        '''
        result = self._values.get("health_check_node_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def internal_traffic_policy(self) -> typing.Optional[builtins.str]:
        '''InternalTrafficPolicy specifies if the cluster internal traffic should be routed to all endpoints or node-local endpoints only.

        "Cluster" routes internal traffic to a Service to all endpoints. "Local" routes traffic to node-local endpoints only, traffic is dropped if no node-local endpoints are ready. The default value is "Cluster".

        :schema: io.k8s.api.core.v1.ServiceSpec#internalTrafficPolicy
        '''
        result = self._values.get("internal_traffic_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ip_families(self) -> typing.Optional[typing.List[builtins.str]]:
        '''IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this service. This field is usually assigned automatically based on cluster configuration and the ipFamilyPolicy field. If this field is specified manually, the requested family is available in the cluster, and ipFamilyPolicy allows it, it will be used; otherwise creation of the service will fail. This field is conditionally mutable: it allows for adding or removing a secondary IP family, but it does not allow changing the primary IP family of the Service. Valid values are "IPv4" and "IPv6".  This field only applies to Services of types ClusterIP, NodePort, and LoadBalancer, and does apply to "headless" services. This field will be wiped when updating a Service to type ExternalName.

        This field may hold a maximum of two entries (dual-stack families, in either order).  These families must correspond to the values of the clusterIPs field, if specified. Both clusterIPs and ipFamilies are governed by the ipFamilyPolicy field.

        :schema: io.k8s.api.core.v1.ServiceSpec#ipFamilies
        '''
        result = self._values.get("ip_families")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def ip_family_policy(self) -> typing.Optional[builtins.str]:
        '''IPFamilyPolicy represents the dual-stack-ness requested or required by this Service.

        If there is no value provided, then this field will be set to SingleStack. Services can be "SingleStack" (a single IP family), "PreferDualStack" (two IP families on dual-stack configured clusters or a single IP family on single-stack clusters), or "RequireDualStack" (two IP families on dual-stack configured clusters, otherwise fail). The ipFamilies and clusterIPs fields depend on the value of this field. This field will be wiped when updating a service to type ExternalName.

        :schema: io.k8s.api.core.v1.ServiceSpec#ipFamilyPolicy
        '''
        result = self._values.get("ip_family_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def load_balancer_class(self) -> typing.Optional[builtins.str]:
        '''loadBalancerClass is the class of the load balancer implementation this Service belongs to.

        If specified, the value of this field must be a label-style identifier, with an optional prefix, e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load balancer implementation is used, today this is typically done through the cloud provider integration, but should apply for any default implementation. If set, it is assumed that a load balancer implementation is watching for Services with a matching class. Any default load balancer implementation (e.g. cloud providers) should ignore Services that set this field. This field can only be set when creating or updating a Service to type 'LoadBalancer'. Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type.

        :schema: io.k8s.api.core.v1.ServiceSpec#loadBalancerClass
        '''
        result = self._values.get("load_balancer_class")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def load_balancer_ip(self) -> typing.Optional[builtins.str]:
        '''Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field.

        This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.

        :schema: io.k8s.api.core.v1.ServiceSpec#loadBalancerIP
        '''
        result = self._values.get("load_balancer_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def load_balancer_source_ranges(self) -> typing.Optional[typing.List[builtins.str]]:
        '''If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs.

        This field will be ignored if the cloud-provider does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/

        :schema: io.k8s.api.core.v1.ServiceSpec#loadBalancerSourceRanges
        '''
        result = self._values.get("load_balancer_source_ranges")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List[ServicePort]]:
        '''The list of ports that are exposed by this service.

        More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

        :schema: io.k8s.api.core.v1.ServiceSpec#ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List[ServicePort]], result)

    @builtins.property
    def publish_not_ready_addresses(self) -> typing.Optional[builtins.bool]:
        '''publishNotReadyAddresses indicates that any agent which deals with endpoints for this Service should disregard any indications of ready/not-ready.

        The primary use case for setting this field is for a StatefulSet's Headless Service to propagate SRV DNS records for its Pods for the purpose of peer discovery. The Kubernetes controllers that generate Endpoints and EndpointSlice resources for Services interpret this to mean that all endpoints are considered "ready" even if the Pods themselves are not. Agents which consume only Kubernetes generated endpoints through the Endpoints or EndpointSlice resources can safely assume this behavior.

        :schema: io.k8s.api.core.v1.ServiceSpec#publishNotReadyAddresses
        '''
        result = self._values.get("publish_not_ready_addresses")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def selector(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Route service traffic to pods with label keys and values matching this selector.

        If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/

        :schema: io.k8s.api.core.v1.ServiceSpec#selector
        '''
        result = self._values.get("selector")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def session_affinity(
        self,
    ) -> typing.Optional[IoK8SApiCoreV1ServiceSpecSessionAffinity]:
        '''Supports "ClientIP" and "None".

        Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

        Possible enum values:

        - ``"ClientIP"`` is the Client IP based.
        - ``"None"`` - no session affinity.

        :default: None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

        :schema: io.k8s.api.core.v1.ServiceSpec#sessionAffinity
        '''
        result = self._values.get("session_affinity")
        return typing.cast(typing.Optional[IoK8SApiCoreV1ServiceSpecSessionAffinity], result)

    @builtins.property
    def session_affinity_config(self) -> typing.Optional["SessionAffinityConfig"]:
        '''sessionAffinityConfig contains the configurations of session affinity.

        :schema: io.k8s.api.core.v1.ServiceSpec#sessionAffinityConfig
        '''
        result = self._values.get("session_affinity_config")
        return typing.cast(typing.Optional["SessionAffinityConfig"], result)

    @builtins.property
    def type(self) -> typing.Optional[IoK8SApiCoreV1ServiceSpecType]:
        '''type determines how the Service is exposed.

        Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object or EndpointSlice objects. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a virtual IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the same endpoints as the clusterIP. "ExternalName" aliases this service to the specified externalName. Several other fields do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

        Possible enum values:

        - ``"ClusterIP"`` means a service will only be accessible inside the cluster, via the cluster IP.
        - ``"ExternalName"`` means a service consists of only a reference to an external name that kubedns or equivalent will return as a CNAME record, with no exposing or proxying of any pods involved.
        - ``"LoadBalancer"`` means a service will be exposed via an external load balancer (if the cloud provider supports it), in addition to 'NodePort' type.
        - ``"NodePort"`` means a service will be exposed on one port of every node, in addition to 'ClusterIP' type.

        :default: ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object or EndpointSlice objects. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a virtual IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the same endpoints as the clusterIP. "ExternalName" aliases this service to the specified externalName. Several other fields do not apply to ExternalName services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

        :schema: io.k8s.api.core.v1.ServiceSpec#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[IoK8SApiCoreV1ServiceSpecType], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SessionAffinityConfig",
    jsii_struct_bases=[],
    name_mapping={"client_ip": "clientIp"},
)
class SessionAffinityConfig:
    def __init__(
        self,
        *,
        client_ip: typing.Optional[typing.Union[ClientIpConfig, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''SessionAffinityConfig represents the configurations of session affinity.

        :param client_ip: clientIP contains the configurations of Client IP based session affinity.

        :schema: io.k8s.api.core.v1.SessionAffinityConfig
        '''
        if isinstance(client_ip, dict):
            client_ip = ClientIpConfig(**client_ip)
        if __debug__:
            def stub(
                *,
                client_ip: typing.Optional[typing.Union[ClientIpConfig, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument client_ip", value=client_ip, expected_type=type_hints["client_ip"])
        self._values: typing.Dict[str, typing.Any] = {}
        if client_ip is not None:
            self._values["client_ip"] = client_ip

    @builtins.property
    def client_ip(self) -> typing.Optional[ClientIpConfig]:
        '''clientIP contains the configurations of Client IP based session affinity.

        :schema: io.k8s.api.core.v1.SessionAffinityConfig#clientIP
        '''
        result = self._values.get("client_ip")
        return typing.cast(typing.Optional[ClientIpConfig], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SessionAffinityConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StatefulSetPersistentVolumeClaimRetentionPolicy",
    jsii_struct_bases=[],
    name_mapping={"when_deleted": "whenDeleted", "when_scaled": "whenScaled"},
)
class StatefulSetPersistentVolumeClaimRetentionPolicy:
    def __init__(
        self,
        *,
        when_deleted: typing.Optional[builtins.str] = None,
        when_scaled: typing.Optional[builtins.str] = None,
    ) -> None:
        '''StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.

        :param when_deleted: WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of ``Retain`` causes PVCs to not be affected by StatefulSet deletion. The ``Delete`` policy causes those PVCs to be deleted.
        :param when_scaled: WhenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. The default policy of ``Retain`` causes PVCs to not be affected by a scaledown. The ``Delete`` policy causes the associated PVCs for any excess pods above the replica count to be deleted.

        :schema: io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy
        '''
        if __debug__:
            def stub(
                *,
                when_deleted: typing.Optional[builtins.str] = None,
                when_scaled: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument when_deleted", value=when_deleted, expected_type=type_hints["when_deleted"])
            check_type(argname="argument when_scaled", value=when_scaled, expected_type=type_hints["when_scaled"])
        self._values: typing.Dict[str, typing.Any] = {}
        if when_deleted is not None:
            self._values["when_deleted"] = when_deleted
        if when_scaled is not None:
            self._values["when_scaled"] = when_scaled

    @builtins.property
    def when_deleted(self) -> typing.Optional[builtins.str]:
        '''WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted.

        The default policy of ``Retain`` causes PVCs to not be affected by StatefulSet deletion. The ``Delete`` policy causes those PVCs to be deleted.

        :schema: io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy#whenDeleted
        '''
        result = self._values.get("when_deleted")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def when_scaled(self) -> typing.Optional[builtins.str]:
        '''WhenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down.

        The default policy of ``Retain`` causes PVCs to not be affected by a scaledown. The ``Delete`` policy causes the associated PVCs for any excess pods above the replica count to be deleted.

        :schema: io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy#whenScaled
        '''
        result = self._values.get("when_scaled")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StatefulSetPersistentVolumeClaimRetentionPolicy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StatefulSetSpec",
    jsii_struct_bases=[],
    name_mapping={
        "selector": "selector",
        "service_name": "serviceName",
        "template": "template",
        "min_ready_seconds": "minReadySeconds",
        "persistent_volume_claim_retention_policy": "persistentVolumeClaimRetentionPolicy",
        "pod_management_policy": "podManagementPolicy",
        "replicas": "replicas",
        "revision_history_limit": "revisionHistoryLimit",
        "update_strategy": "updateStrategy",
        "volume_claim_templates": "volumeClaimTemplates",
    },
)
class StatefulSetSpec:
    def __init__(
        self,
        *,
        selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
        service_name: builtins.str,
        template: typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]],
        min_ready_seconds: typing.Optional[jsii.Number] = None,
        persistent_volume_claim_retention_policy: typing.Optional[typing.Union[StatefulSetPersistentVolumeClaimRetentionPolicy, typing.Dict[str, typing.Any]]] = None,
        pod_management_policy: typing.Optional[IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy] = None,
        replicas: typing.Optional[jsii.Number] = None,
        revision_history_limit: typing.Optional[jsii.Number] = None,
        update_strategy: typing.Optional[typing.Union["StatefulSetUpdateStrategy", typing.Dict[str, typing.Any]]] = None,
        volume_claim_templates: typing.Optional[typing.Sequence[typing.Union[KubePersistentVolumeClaimProps, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''A StatefulSetSpec is the specification of a StatefulSet.

        :param selector: selector is a label query over pods that should match the replica count. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
        :param service_name: serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where "pod-specific-string" is managed by the StatefulSet controller.
        :param template: template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.
        :param min_ready_seconds: Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. Default: 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.
        :param persistent_volume_claim_retention_policy: persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. +optional
        :param pod_management_policy: podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is ``OrderedReady``, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is ``Parallel`` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once. Possible enum values: - ``"OrderedReady"`` will create pods in strictly increasing order on scale up and strictly decreasing order on scale down, progressing only when the previous pod is ready or terminated. At most one pod will be changed at any time. - ``"Parallel"`` will create and delete pods as soon as the stateful set replica count is changed, and will not wait for pods to be ready or complete termination.
        :param replicas: replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.
        :param revision_history_limit: revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.
        :param update_strategy: updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.
        :param volume_claim_templates: volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec
        '''
        if isinstance(selector, dict):
            selector = LabelSelector(**selector)
        if isinstance(template, dict):
            template = PodTemplateSpec(**template)
        if isinstance(persistent_volume_claim_retention_policy, dict):
            persistent_volume_claim_retention_policy = StatefulSetPersistentVolumeClaimRetentionPolicy(**persistent_volume_claim_retention_policy)
        if isinstance(update_strategy, dict):
            update_strategy = StatefulSetUpdateStrategy(**update_strategy)
        if __debug__:
            def stub(
                *,
                selector: typing.Union[LabelSelector, typing.Dict[str, typing.Any]],
                service_name: builtins.str,
                template: typing.Union[PodTemplateSpec, typing.Dict[str, typing.Any]],
                min_ready_seconds: typing.Optional[jsii.Number] = None,
                persistent_volume_claim_retention_policy: typing.Optional[typing.Union[StatefulSetPersistentVolumeClaimRetentionPolicy, typing.Dict[str, typing.Any]]] = None,
                pod_management_policy: typing.Optional[IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy] = None,
                replicas: typing.Optional[jsii.Number] = None,
                revision_history_limit: typing.Optional[jsii.Number] = None,
                update_strategy: typing.Optional[typing.Union[StatefulSetUpdateStrategy, typing.Dict[str, typing.Any]]] = None,
                volume_claim_templates: typing.Optional[typing.Sequence[typing.Union[KubePersistentVolumeClaimProps, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument selector", value=selector, expected_type=type_hints["selector"])
            check_type(argname="argument service_name", value=service_name, expected_type=type_hints["service_name"])
            check_type(argname="argument template", value=template, expected_type=type_hints["template"])
            check_type(argname="argument min_ready_seconds", value=min_ready_seconds, expected_type=type_hints["min_ready_seconds"])
            check_type(argname="argument persistent_volume_claim_retention_policy", value=persistent_volume_claim_retention_policy, expected_type=type_hints["persistent_volume_claim_retention_policy"])
            check_type(argname="argument pod_management_policy", value=pod_management_policy, expected_type=type_hints["pod_management_policy"])
            check_type(argname="argument replicas", value=replicas, expected_type=type_hints["replicas"])
            check_type(argname="argument revision_history_limit", value=revision_history_limit, expected_type=type_hints["revision_history_limit"])
            check_type(argname="argument update_strategy", value=update_strategy, expected_type=type_hints["update_strategy"])
            check_type(argname="argument volume_claim_templates", value=volume_claim_templates, expected_type=type_hints["volume_claim_templates"])
        self._values: typing.Dict[str, typing.Any] = {
            "selector": selector,
            "service_name": service_name,
            "template": template,
        }
        if min_ready_seconds is not None:
            self._values["min_ready_seconds"] = min_ready_seconds
        if persistent_volume_claim_retention_policy is not None:
            self._values["persistent_volume_claim_retention_policy"] = persistent_volume_claim_retention_policy
        if pod_management_policy is not None:
            self._values["pod_management_policy"] = pod_management_policy
        if replicas is not None:
            self._values["replicas"] = replicas
        if revision_history_limit is not None:
            self._values["revision_history_limit"] = revision_history_limit
        if update_strategy is not None:
            self._values["update_strategy"] = update_strategy
        if volume_claim_templates is not None:
            self._values["volume_claim_templates"] = volume_claim_templates

    @builtins.property
    def selector(self) -> LabelSelector:
        '''selector is a label query over pods that should match the replica count.

        It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#selector
        '''
        result = self._values.get("selector")
        assert result is not None, "Required property 'selector' is missing"
        return typing.cast(LabelSelector, result)

    @builtins.property
    def service_name(self) -> builtins.str:
        '''serviceName is the name of the service that governs this StatefulSet.

        This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where "pod-specific-string" is managed by the StatefulSet controller.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#serviceName
        '''
        result = self._values.get("service_name")
        assert result is not None, "Required property 'service_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def template(self) -> PodTemplateSpec:
        '''template is the object that describes the pod that will be created if insufficient replicas are detected.

        Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#template
        '''
        result = self._values.get("template")
        assert result is not None, "Required property 'template' is missing"
        return typing.cast(PodTemplateSpec, result)

    @builtins.property
    def min_ready_seconds(self) -> typing.Optional[jsii.Number]:
        '''Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available.

        Defaults to 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.

        :default: 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#minReadySeconds
        '''
        result = self._values.get("min_ready_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def persistent_volume_claim_retention_policy(
        self,
    ) -> typing.Optional[StatefulSetPersistentVolumeClaimRetentionPolicy]:
        '''persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates.

        By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha.  +optional

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#persistentVolumeClaimRetentionPolicy
        '''
        result = self._values.get("persistent_volume_claim_retention_policy")
        return typing.cast(typing.Optional[StatefulSetPersistentVolumeClaimRetentionPolicy], result)

    @builtins.property
    def pod_management_policy(
        self,
    ) -> typing.Optional[IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy]:
        '''podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down.

        The default policy is ``OrderedReady``, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is ``Parallel`` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.

        Possible enum values:

        - ``"OrderedReady"`` will create pods in strictly increasing order on scale up and strictly decreasing order on scale down, progressing only when the previous pod is ready or terminated. At most one pod will be changed at any time.
        - ``"Parallel"`` will create and delete pods as soon as the stateful set replica count is changed, and will not wait for pods to be ready or complete termination.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#podManagementPolicy
        '''
        result = self._values.get("pod_management_policy")
        return typing.cast(typing.Optional[IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy], result)

    @builtins.property
    def replicas(self) -> typing.Optional[jsii.Number]:
        '''replicas is the desired number of replicas of the given Template.

        These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#replicas
        '''
        result = self._values.get("replicas")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def revision_history_limit(self) -> typing.Optional[jsii.Number]:
        '''revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history.

        The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#revisionHistoryLimit
        '''
        result = self._values.get("revision_history_limit")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def update_strategy(self) -> typing.Optional["StatefulSetUpdateStrategy"]:
        '''updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#updateStrategy
        '''
        result = self._values.get("update_strategy")
        return typing.cast(typing.Optional["StatefulSetUpdateStrategy"], result)

    @builtins.property
    def volume_claim_templates(
        self,
    ) -> typing.Optional[typing.List[KubePersistentVolumeClaimProps]]:
        '''volumeClaimTemplates is a list of claims that pods are allowed to reference.

        The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.

        :schema: io.k8s.api.apps.v1.StatefulSetSpec#volumeClaimTemplates
        '''
        result = self._values.get("volume_claim_templates")
        return typing.cast(typing.Optional[typing.List[KubePersistentVolumeClaimProps]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StatefulSetSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StatefulSetUpdateStrategy",
    jsii_struct_bases=[],
    name_mapping={"rolling_update": "rollingUpdate", "type": "type"},
)
class StatefulSetUpdateStrategy:
    def __init__(
        self,
        *,
        rolling_update: typing.Optional[typing.Union[RollingUpdateStatefulSetStrategy, typing.Dict[str, typing.Any]]] = None,
        type: typing.Optional[IoK8SApiAppsV1StatefulSetUpdateStrategyType] = None,
    ) -> None:
        '''StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates.

        It includes any additional parameters necessary to perform the update for the indicated strategy.

        :param rolling_update: RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType.
        :param type: Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate. Possible enum values: - ``"OnDelete"`` triggers the legacy behavior. Version tracking and ordered rolling restarts are disabled. Pods are recreated from the StatefulSetSpec when they are manually deleted. When a scale operation is performed with this strategy,specification version indicated by the StatefulSet's currentRevision. - ``"RollingUpdate"`` indicates that update will be applied to all Pods in the StatefulSet with respect to the StatefulSet ordering constraints. When a scale operation is performed with this strategy, new Pods will be created from the specification version indicated by the StatefulSet's updateRevision. Default: RollingUpdate.

        :schema: io.k8s.api.apps.v1.StatefulSetUpdateStrategy
        '''
        if isinstance(rolling_update, dict):
            rolling_update = RollingUpdateStatefulSetStrategy(**rolling_update)
        if __debug__:
            def stub(
                *,
                rolling_update: typing.Optional[typing.Union[RollingUpdateStatefulSetStrategy, typing.Dict[str, typing.Any]]] = None,
                type: typing.Optional[IoK8SApiAppsV1StatefulSetUpdateStrategyType] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rolling_update", value=rolling_update, expected_type=type_hints["rolling_update"])
            check_type(argname="argument type", value=type, expected_type=type_hints["type"])
        self._values: typing.Dict[str, typing.Any] = {}
        if rolling_update is not None:
            self._values["rolling_update"] = rolling_update
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def rolling_update(self) -> typing.Optional[RollingUpdateStatefulSetStrategy]:
        '''RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType.

        :schema: io.k8s.api.apps.v1.StatefulSetUpdateStrategy#rollingUpdate
        '''
        result = self._values.get("rolling_update")
        return typing.cast(typing.Optional[RollingUpdateStatefulSetStrategy], result)

    @builtins.property
    def type(self) -> typing.Optional[IoK8SApiAppsV1StatefulSetUpdateStrategyType]:
        '''Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate.

        Possible enum values:

        - ``"OnDelete"`` triggers the legacy behavior. Version tracking and ordered rolling restarts are disabled. Pods are recreated from the StatefulSetSpec when they are manually deleted. When a scale operation is performed with this strategy,specification version indicated by the StatefulSet's currentRevision.
        - ``"RollingUpdate"`` indicates that update will be applied to all Pods in the StatefulSet with respect to the StatefulSet ordering constraints. When a scale operation is performed with this strategy, new Pods will be created from the specification version indicated by the StatefulSet's updateRevision.

        :default: RollingUpdate.

        :schema: io.k8s.api.apps.v1.StatefulSetUpdateStrategy#type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[IoK8SApiAppsV1StatefulSetUpdateStrategyType], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StatefulSetUpdateStrategy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StatusCause",
    jsii_struct_bases=[],
    name_mapping={"field": "field", "message": "message", "reason": "reason"},
)
class StatusCause:
    def __init__(
        self,
        *,
        field: typing.Optional[builtins.str] = None,
        message: typing.Optional[builtins.str] = None,
        reason: typing.Optional[builtins.str] = None,
    ) -> None:
        '''StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.

        :param field: The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. Examples: "name" - the field "name" on the current resource "items[0].name" - the field "name" on the first array entry in "items"
        :param message: A human-readable description of the cause of the error. This field may be presented as-is to a reader.
        :param reason: A machine-readable description of the cause of the error. If this value is empty there is no information available.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause
        '''
        if __debug__:
            def stub(
                *,
                field: typing.Optional[builtins.str] = None,
                message: typing.Optional[builtins.str] = None,
                reason: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument field", value=field, expected_type=type_hints["field"])
            check_type(argname="argument message", value=message, expected_type=type_hints["message"])
            check_type(argname="argument reason", value=reason, expected_type=type_hints["reason"])
        self._values: typing.Dict[str, typing.Any] = {}
        if field is not None:
            self._values["field"] = field
        if message is not None:
            self._values["message"] = message
        if reason is not None:
            self._values["reason"] = reason

    @builtins.property
    def field(self) -> typing.Optional[builtins.str]:
        '''The field of the resource that has caused this error, as named by its JSON serialization.

        May include dot and postfix notation for nested attributes. Arrays are zero-indexed.  Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.

        Examples:
        "name" - the field "name" on the current resource
        "items[0].name" - the field "name" on the first array entry in "items"

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause#field
        '''
        result = self._values.get("field")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def message(self) -> typing.Optional[builtins.str]:
        '''A human-readable description of the cause of the error.

        This field may be presented as-is to a reader.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause#message
        '''
        result = self._values.get("message")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def reason(self) -> typing.Optional[builtins.str]:
        '''A machine-readable description of the cause of the error.

        If this value is empty there is no information available.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause#reason
        '''
        result = self._values.get("reason")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StatusCause(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StatusDetails",
    jsii_struct_bases=[],
    name_mapping={
        "causes": "causes",
        "group": "group",
        "kind": "kind",
        "name": "name",
        "retry_after_seconds": "retryAfterSeconds",
        "uid": "uid",
    },
)
class StatusDetails:
    def __init__(
        self,
        *,
        causes: typing.Optional[typing.Sequence[typing.Union[StatusCause, typing.Dict[str, typing.Any]]]] = None,
        group: typing.Optional[builtins.str] = None,
        kind: typing.Optional[builtins.str] = None,
        name: typing.Optional[builtins.str] = None,
        retry_after_seconds: typing.Optional[jsii.Number] = None,
        uid: typing.Optional[builtins.str] = None,
    ) -> None:
        '''StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response.

        The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.

        :param causes: The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.
        :param group: The group attribute of the resource associated with the status StatusReason.
        :param kind: The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
        :param name: The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).
        :param retry_after_seconds: If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.
        :param uid: UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails
        '''
        if __debug__:
            def stub(
                *,
                causes: typing.Optional[typing.Sequence[typing.Union[StatusCause, typing.Dict[str, typing.Any]]]] = None,
                group: typing.Optional[builtins.str] = None,
                kind: typing.Optional[builtins.str] = None,
                name: typing.Optional[builtins.str] = None,
                retry_after_seconds: typing.Optional[jsii.Number] = None,
                uid: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument causes", value=causes, expected_type=type_hints["causes"])
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument retry_after_seconds", value=retry_after_seconds, expected_type=type_hints["retry_after_seconds"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
        self._values: typing.Dict[str, typing.Any] = {}
        if causes is not None:
            self._values["causes"] = causes
        if group is not None:
            self._values["group"] = group
        if kind is not None:
            self._values["kind"] = kind
        if name is not None:
            self._values["name"] = name
        if retry_after_seconds is not None:
            self._values["retry_after_seconds"] = retry_after_seconds
        if uid is not None:
            self._values["uid"] = uid

    @builtins.property
    def causes(self) -> typing.Optional[typing.List[StatusCause]]:
        '''The Causes array includes more details associated with the StatusReason failure.

        Not all StatusReasons may provide detailed causes.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails#causes
        '''
        result = self._values.get("causes")
        return typing.cast(typing.Optional[typing.List[StatusCause]], result)

    @builtins.property
    def group(self) -> typing.Optional[builtins.str]:
        '''The group attribute of the resource associated with the status StatusReason.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails#group
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def kind(self) -> typing.Optional[builtins.str]:
        '''The kind attribute of the resource associated with the status StatusReason.

        On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails#kind
        '''
        result = self._values.get("kind")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def name(self) -> typing.Optional[builtins.str]:
        '''The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails#name
        '''
        result = self._values.get("name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def retry_after_seconds(self) -> typing.Optional[jsii.Number]:
        '''If specified, the time in seconds before the operation should be retried.

        Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails#retryAfterSeconds
        '''
        result = self._values.get("retry_after_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''UID of the resource.

        (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids

        :schema: io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StatusDetails(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StorageOsPersistentVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "fs_type": "fsType",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
        "volume_name": "volumeName",
        "volume_namespace": "volumeNamespace",
    },
)
class StorageOsPersistentVolumeSource:
    def __init__(
        self,
        *,
        fs_type: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
        volume_name: typing.Optional[builtins.str] = None,
        volume_namespace: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a StorageOS persistent volume resource.

        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param secret_ref: SecretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted.
        :param volume_name: VolumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.
        :param volume_namespace: VolumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created.

        :schema: io.k8s.api.core.v1.StorageOSPersistentVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = ObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                fs_type: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[ObjectReference, typing.Dict[str, typing.Any]]] = None,
                volume_name: typing.Optional[builtins.str] = None,
                volume_namespace: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument volume_name", value=volume_name, expected_type=type_hints["volume_name"])
            check_type(argname="argument volume_namespace", value=volume_namespace, expected_type=type_hints["volume_namespace"])
        self._values: typing.Dict[str, typing.Any] = {}
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref
        if volume_name is not None:
            self._values["volume_name"] = volume_name
        if volume_namespace is not None:
            self._values["volume_namespace"] = volume_namespace

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.StorageOSPersistentVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.StorageOSPersistentVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional[ObjectReference]:
        '''SecretRef specifies the secret to use for obtaining the StorageOS API credentials.

        If not specified, default values will be attempted.

        :schema: io.k8s.api.core.v1.StorageOSPersistentVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional[ObjectReference], result)

    @builtins.property
    def volume_name(self) -> typing.Optional[builtins.str]:
        '''VolumeName is the human-readable name of the StorageOS volume.

        Volume names are only unique within a namespace.

        :schema: io.k8s.api.core.v1.StorageOSPersistentVolumeSource#volumeName
        '''
        result = self._values.get("volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_namespace(self) -> typing.Optional[builtins.str]:
        '''VolumeNamespace specifies the scope of the volume within StorageOS.

        If no namespace is specified then the Pod's namespace will be used.  This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created.

        :schema: io.k8s.api.core.v1.StorageOSPersistentVolumeSource#volumeNamespace
        '''
        result = self._values.get("volume_namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StorageOsPersistentVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.StorageOsVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "fs_type": "fsType",
        "read_only": "readOnly",
        "secret_ref": "secretRef",
        "volume_name": "volumeName",
        "volume_namespace": "volumeNamespace",
    },
)
class StorageOsVolumeSource:
    def __init__(
        self,
        *,
        fs_type: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
        volume_name: typing.Optional[builtins.str] = None,
        volume_namespace: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a StorageOS persistent volume resource.

        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
        :param read_only: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. Default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.
        :param secret_ref: SecretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted.
        :param volume_name: VolumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.
        :param volume_namespace: VolumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created.

        :schema: io.k8s.api.core.v1.StorageOSVolumeSource
        '''
        if isinstance(secret_ref, dict):
            secret_ref = LocalObjectReference(**secret_ref)
        if __debug__:
            def stub(
                *,
                fs_type: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                secret_ref: typing.Optional[typing.Union[LocalObjectReference, typing.Dict[str, typing.Any]]] = None,
                volume_name: typing.Optional[builtins.str] = None,
                volume_namespace: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument secret_ref", value=secret_ref, expected_type=type_hints["secret_ref"])
            check_type(argname="argument volume_name", value=volume_name, expected_type=type_hints["volume_name"])
            check_type(argname="argument volume_namespace", value=volume_namespace, expected_type=type_hints["volume_namespace"])
        self._values: typing.Dict[str, typing.Any] = {}
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if read_only is not None:
            self._values["read_only"] = read_only
        if secret_ref is not None:
            self._values["secret_ref"] = secret_ref
        if volume_name is not None:
            self._values["volume_name"] = volume_name
        if volume_namespace is not None:
            self._values["volume_namespace"] = volume_namespace

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.StorageOSVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Defaults to false (read/write).

        ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :default: false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

        :schema: io.k8s.api.core.v1.StorageOSVolumeSource#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def secret_ref(self) -> typing.Optional[LocalObjectReference]:
        '''SecretRef specifies the secret to use for obtaining the StorageOS API credentials.

        If not specified, default values will be attempted.

        :schema: io.k8s.api.core.v1.StorageOSVolumeSource#secretRef
        '''
        result = self._values.get("secret_ref")
        return typing.cast(typing.Optional[LocalObjectReference], result)

    @builtins.property
    def volume_name(self) -> typing.Optional[builtins.str]:
        '''VolumeName is the human-readable name of the StorageOS volume.

        Volume names are only unique within a namespace.

        :schema: io.k8s.api.core.v1.StorageOSVolumeSource#volumeName
        '''
        result = self._values.get("volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_namespace(self) -> typing.Optional[builtins.str]:
        '''VolumeNamespace specifies the scope of the volume within StorageOS.

        If no namespace is specified then the Pod's namespace will be used.  This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created.

        :schema: io.k8s.api.core.v1.StorageOSVolumeSource#volumeNamespace
        '''
        result = self._values.get("volume_namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "StorageOsVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Subject",
    jsii_struct_bases=[],
    name_mapping={
        "kind": "kind",
        "name": "name",
        "api_group": "apiGroup",
        "namespace": "namespace",
    },
)
class Subject:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_group: typing.Optional[builtins.str] = None,
        namespace: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Subject contains a reference to the object or user identities a role binding applies to.

        This can either hold a direct API object reference, or a value for non-objects such as user and group names.

        :param kind: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error.
        :param name: Name of the object being referenced.
        :param api_group: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. Default: for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
        :param namespace: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error.

        :schema: io.k8s.api.rbac.v1.Subject
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_group: typing.Optional[builtins.str] = None,
                namespace: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_group", value=api_group, expected_type=type_hints["api_group"])
            check_type(argname="argument namespace", value=namespace, expected_type=type_hints["namespace"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_group is not None:
            self._values["api_group"] = api_group
        if namespace is not None:
            self._values["namespace"] = namespace

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind of object being referenced.

        Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error.

        :schema: io.k8s.api.rbac.v1.Subject#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the object being referenced.

        :schema: io.k8s.api.rbac.v1.Subject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_group(self) -> typing.Optional[builtins.str]:
        '''APIGroup holds the API group of the referenced subject.

        Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects.

        :default: for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects.

        :schema: io.k8s.api.rbac.v1.Subject#apiGroup
        '''
        result = self._values.get("api_group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace(self) -> typing.Optional[builtins.str]:
        '''Namespace of the referenced object.

        If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error.

        :schema: io.k8s.api.rbac.v1.Subject#namespace
        '''
        result = self._values.get("namespace")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Subject(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SubjectAccessReviewSpec",
    jsii_struct_bases=[],
    name_mapping={
        "extra": "extra",
        "groups": "groups",
        "non_resource_attributes": "nonResourceAttributes",
        "resource_attributes": "resourceAttributes",
        "uid": "uid",
        "user": "user",
    },
)
class SubjectAccessReviewSpec:
    def __init__(
        self,
        *,
        extra: typing.Optional[typing.Mapping[builtins.str, typing.Sequence[builtins.str]]] = None,
        groups: typing.Optional[typing.Sequence[builtins.str]] = None,
        non_resource_attributes: typing.Optional[typing.Union[NonResourceAttributes, typing.Dict[str, typing.Any]]] = None,
        resource_attributes: typing.Optional[typing.Union[ResourceAttributes, typing.Dict[str, typing.Any]]] = None,
        uid: typing.Optional[builtins.str] = None,
        user: typing.Optional[builtins.str] = None,
    ) -> None:
        '''SubjectAccessReviewSpec is a description of the access request.

        Exactly one of ResourceAuthorizationAttributes and NonResourceAuthorizationAttributes must be set

        :param extra: Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer it needs a reflection here.
        :param groups: Groups is the groups you're testing for.
        :param non_resource_attributes: NonResourceAttributes describes information for a non-resource access request.
        :param resource_attributes: ResourceAuthorizationAttributes describes information for a resource access request.
        :param uid: UID information about the requesting user.
        :param user: User is the user you're testing for. If you specify "User" but not "Groups", then is it interpreted as "What if User were not a member of any groups

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec
        '''
        if isinstance(non_resource_attributes, dict):
            non_resource_attributes = NonResourceAttributes(**non_resource_attributes)
        if isinstance(resource_attributes, dict):
            resource_attributes = ResourceAttributes(**resource_attributes)
        if __debug__:
            def stub(
                *,
                extra: typing.Optional[typing.Mapping[builtins.str, typing.Sequence[builtins.str]]] = None,
                groups: typing.Optional[typing.Sequence[builtins.str]] = None,
                non_resource_attributes: typing.Optional[typing.Union[NonResourceAttributes, typing.Dict[str, typing.Any]]] = None,
                resource_attributes: typing.Optional[typing.Union[ResourceAttributes, typing.Dict[str, typing.Any]]] = None,
                uid: typing.Optional[builtins.str] = None,
                user: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument extra", value=extra, expected_type=type_hints["extra"])
            check_type(argname="argument groups", value=groups, expected_type=type_hints["groups"])
            check_type(argname="argument non_resource_attributes", value=non_resource_attributes, expected_type=type_hints["non_resource_attributes"])
            check_type(argname="argument resource_attributes", value=resource_attributes, expected_type=type_hints["resource_attributes"])
            check_type(argname="argument uid", value=uid, expected_type=type_hints["uid"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {}
        if extra is not None:
            self._values["extra"] = extra
        if groups is not None:
            self._values["groups"] = groups
        if non_resource_attributes is not None:
            self._values["non_resource_attributes"] = non_resource_attributes
        if resource_attributes is not None:
            self._values["resource_attributes"] = resource_attributes
        if uid is not None:
            self._values["uid"] = uid
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def extra(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]]:
        '''Extra corresponds to the user.Info.GetExtra() method from the authenticator.  Since that is input to the authorizer it needs a reflection here.

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec#extra
        '''
        result = self._values.get("extra")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]], result)

    @builtins.property
    def groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Groups is the groups you're testing for.

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec#groups
        '''
        result = self._values.get("groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def non_resource_attributes(self) -> typing.Optional[NonResourceAttributes]:
        '''NonResourceAttributes describes information for a non-resource access request.

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec#nonResourceAttributes
        '''
        result = self._values.get("non_resource_attributes")
        return typing.cast(typing.Optional[NonResourceAttributes], result)

    @builtins.property
    def resource_attributes(self) -> typing.Optional[ResourceAttributes]:
        '''ResourceAuthorizationAttributes describes information for a resource access request.

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec#resourceAttributes
        '''
        result = self._values.get("resource_attributes")
        return typing.cast(typing.Optional[ResourceAttributes], result)

    @builtins.property
    def uid(self) -> typing.Optional[builtins.str]:
        '''UID information about the requesting user.

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec#uid
        '''
        result = self._values.get("uid")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def user(self) -> typing.Optional[builtins.str]:
        '''User is the user you're testing for.

        If you specify "User" but not "Groups", then is it interpreted as "What if User were not a member of any groups

        :schema: io.k8s.api.authorization.v1.SubjectAccessReviewSpec#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubjectAccessReviewSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SubjectV1Beta1",
    jsii_struct_bases=[],
    name_mapping={
        "kind": "kind",
        "group": "group",
        "service_account": "serviceAccount",
        "user": "user",
    },
)
class SubjectV1Beta1:
    def __init__(
        self,
        *,
        kind: builtins.str,
        group: typing.Optional[typing.Union[GroupSubjectV1Beta1, typing.Dict[str, typing.Any]]] = None,
        service_account: typing.Optional[typing.Union[ServiceAccountSubjectV1Beta1, typing.Dict[str, typing.Any]]] = None,
        user: typing.Optional[typing.Union["UserSubjectV1Beta1", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Subject matches the originator of a request, as identified by the request authentication system.

        There are three ways of matching an originator; by user, group, or service account.

        :param kind: ``kind`` indicates which one of the other fields is non-empty. Required
        :param group: ``group`` matches based on user group name.
        :param service_account: ``serviceAccount`` matches ServiceAccounts.
        :param user: ``user`` matches based on username.

        :schema: io.k8s.api.flowcontrol.v1beta1.Subject
        '''
        if isinstance(group, dict):
            group = GroupSubjectV1Beta1(**group)
        if isinstance(service_account, dict):
            service_account = ServiceAccountSubjectV1Beta1(**service_account)
        if isinstance(user, dict):
            user = UserSubjectV1Beta1(**user)
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                group: typing.Optional[typing.Union[GroupSubjectV1Beta1, typing.Dict[str, typing.Any]]] = None,
                service_account: typing.Optional[typing.Union[ServiceAccountSubjectV1Beta1, typing.Dict[str, typing.Any]]] = None,
                user: typing.Optional[typing.Union[UserSubjectV1Beta1, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument service_account", value=service_account, expected_type=type_hints["service_account"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
        }
        if group is not None:
            self._values["group"] = group
        if service_account is not None:
            self._values["service_account"] = service_account
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def kind(self) -> builtins.str:
        '''``kind`` indicates which one of the other fields is non-empty.

        Required

        :schema: io.k8s.api.flowcontrol.v1beta1.Subject#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def group(self) -> typing.Optional[GroupSubjectV1Beta1]:
        '''``group`` matches based on user group name.

        :schema: io.k8s.api.flowcontrol.v1beta1.Subject#group
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[GroupSubjectV1Beta1], result)

    @builtins.property
    def service_account(self) -> typing.Optional[ServiceAccountSubjectV1Beta1]:
        '''``serviceAccount`` matches ServiceAccounts.

        :schema: io.k8s.api.flowcontrol.v1beta1.Subject#serviceAccount
        '''
        result = self._values.get("service_account")
        return typing.cast(typing.Optional[ServiceAccountSubjectV1Beta1], result)

    @builtins.property
    def user(self) -> typing.Optional["UserSubjectV1Beta1"]:
        '''``user`` matches based on username.

        :schema: io.k8s.api.flowcontrol.v1beta1.Subject#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional["UserSubjectV1Beta1"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubjectV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SubjectV1Beta2",
    jsii_struct_bases=[],
    name_mapping={
        "kind": "kind",
        "group": "group",
        "service_account": "serviceAccount",
        "user": "user",
    },
)
class SubjectV1Beta2:
    def __init__(
        self,
        *,
        kind: builtins.str,
        group: typing.Optional[typing.Union[GroupSubjectV1Beta2, typing.Dict[str, typing.Any]]] = None,
        service_account: typing.Optional[typing.Union[ServiceAccountSubjectV1Beta2, typing.Dict[str, typing.Any]]] = None,
        user: typing.Optional[typing.Union["UserSubjectV1Beta2", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Subject matches the originator of a request, as identified by the request authentication system.

        There are three ways of matching an originator; by user, group, or service account.

        :param kind: ``kind`` indicates which one of the other fields is non-empty. Required
        :param group: ``group`` matches based on user group name.
        :param service_account: ``serviceAccount`` matches ServiceAccounts.
        :param user: ``user`` matches based on username.

        :schema: io.k8s.api.flowcontrol.v1beta2.Subject
        '''
        if isinstance(group, dict):
            group = GroupSubjectV1Beta2(**group)
        if isinstance(service_account, dict):
            service_account = ServiceAccountSubjectV1Beta2(**service_account)
        if isinstance(user, dict):
            user = UserSubjectV1Beta2(**user)
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                group: typing.Optional[typing.Union[GroupSubjectV1Beta2, typing.Dict[str, typing.Any]]] = None,
                service_account: typing.Optional[typing.Union[ServiceAccountSubjectV1Beta2, typing.Dict[str, typing.Any]]] = None,
                user: typing.Optional[typing.Union[UserSubjectV1Beta2, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument group", value=group, expected_type=type_hints["group"])
            check_type(argname="argument service_account", value=service_account, expected_type=type_hints["service_account"])
            check_type(argname="argument user", value=user, expected_type=type_hints["user"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
        }
        if group is not None:
            self._values["group"] = group
        if service_account is not None:
            self._values["service_account"] = service_account
        if user is not None:
            self._values["user"] = user

    @builtins.property
    def kind(self) -> builtins.str:
        '''``kind`` indicates which one of the other fields is non-empty.

        Required

        :schema: io.k8s.api.flowcontrol.v1beta2.Subject#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def group(self) -> typing.Optional[GroupSubjectV1Beta2]:
        '''``group`` matches based on user group name.

        :schema: io.k8s.api.flowcontrol.v1beta2.Subject#group
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[GroupSubjectV1Beta2], result)

    @builtins.property
    def service_account(self) -> typing.Optional[ServiceAccountSubjectV1Beta2]:
        '''``serviceAccount`` matches ServiceAccounts.

        :schema: io.k8s.api.flowcontrol.v1beta2.Subject#serviceAccount
        '''
        result = self._values.get("service_account")
        return typing.cast(typing.Optional[ServiceAccountSubjectV1Beta2], result)

    @builtins.property
    def user(self) -> typing.Optional["UserSubjectV1Beta2"]:
        '''``user`` matches based on username.

        :schema: io.k8s.api.flowcontrol.v1beta2.Subject#user
        '''
        result = self._values.get("user")
        return typing.cast(typing.Optional["UserSubjectV1Beta2"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubjectV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.SupplementalGroupsStrategyOptionsV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"ranges": "ranges", "rule": "rule"},
)
class SupplementalGroupsStrategyOptionsV1Beta1:
    def __init__(
        self,
        *,
        ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
        rule: typing.Optional[builtins.str] = None,
    ) -> None:
        '''SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy.

        :param ranges: ranges are the allowed ranges of supplemental groups. If you would like to force a single supplemental group then supply a single range with the same start and end. Required for MustRunAs.
        :param rule: rule is the strategy that will dictate what supplemental groups is used in the SecurityContext.

        :schema: io.k8s.api.policy.v1beta1.SupplementalGroupsStrategyOptions
        '''
        if __debug__:
            def stub(
                *,
                ranges: typing.Optional[typing.Sequence[typing.Union[IdRangeV1Beta1, typing.Dict[str, typing.Any]]]] = None,
                rule: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ranges", value=ranges, expected_type=type_hints["ranges"])
            check_type(argname="argument rule", value=rule, expected_type=type_hints["rule"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ranges is not None:
            self._values["ranges"] = ranges
        if rule is not None:
            self._values["rule"] = rule

    @builtins.property
    def ranges(self) -> typing.Optional[typing.List[IdRangeV1Beta1]]:
        '''ranges are the allowed ranges of supplemental groups.

        If you would like to force a single supplemental group then supply a single range with the same start and end. Required for MustRunAs.

        :schema: io.k8s.api.policy.v1beta1.SupplementalGroupsStrategyOptions#ranges
        '''
        result = self._values.get("ranges")
        return typing.cast(typing.Optional[typing.List[IdRangeV1Beta1]], result)

    @builtins.property
    def rule(self) -> typing.Optional[builtins.str]:
        '''rule is the strategy that will dictate what supplemental groups is used in the SecurityContext.

        :schema: io.k8s.api.policy.v1beta1.SupplementalGroupsStrategyOptions#rule
        '''
        result = self._values.get("rule")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SupplementalGroupsStrategyOptionsV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Sysctl",
    jsii_struct_bases=[],
    name_mapping={"name": "name", "value": "value"},
)
class Sysctl:
    def __init__(self, *, name: builtins.str, value: builtins.str) -> None:
        '''Sysctl defines a kernel parameter to be set.

        :param name: Name of a property to set.
        :param value: Value of a property to set.

        :schema: io.k8s.api.core.v1.Sysctl
        '''
        if __debug__:
            def stub(*, name: builtins.str, value: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "value": value,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of a property to set.

        :schema: io.k8s.api.core.v1.Sysctl#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def value(self) -> builtins.str:
        '''Value of a property to set.

        :schema: io.k8s.api.core.v1.Sysctl#value
        '''
        result = self._values.get("value")
        assert result is not None, "Required property 'value' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Sysctl(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Taint",
    jsii_struct_bases=[],
    name_mapping={
        "effect": "effect",
        "key": "key",
        "time_added": "timeAdded",
        "value": "value",
    },
)
class Taint:
    def __init__(
        self,
        *,
        effect: IoK8SApiCoreV1TaintEffect,
        key: builtins.str,
        time_added: typing.Optional[datetime.datetime] = None,
        value: typing.Optional[builtins.str] = None,
    ) -> None:
        '''The node this Taint is attached to has the "effect" on any pod that does not tolerate the Taint.

        :param effect: Required. The effect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule and NoExecute. Possible enum values: - ``"NoExecute"`` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController. - ``"NoSchedule"`` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler. - ``"PreferNoSchedule"`` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler.
        :param key: Required. The taint key to be applied to a node.
        :param time_added: TimeAdded represents the time at which the taint was added. It is only written for NoExecute taints.
        :param value: The taint value corresponding to the taint key.

        :schema: io.k8s.api.core.v1.Taint
        '''
        if __debug__:
            def stub(
                *,
                effect: IoK8SApiCoreV1TaintEffect,
                key: builtins.str,
                time_added: typing.Optional[datetime.datetime] = None,
                value: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument effect", value=effect, expected_type=type_hints["effect"])
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument time_added", value=time_added, expected_type=type_hints["time_added"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {
            "effect": effect,
            "key": key,
        }
        if time_added is not None:
            self._values["time_added"] = time_added
        if value is not None:
            self._values["value"] = value

    @builtins.property
    def effect(self) -> IoK8SApiCoreV1TaintEffect:
        '''Required.

        The effect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule and NoExecute.

        Possible enum values:

        - ``"NoExecute"`` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController.
        - ``"NoSchedule"`` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler.
        - ``"PreferNoSchedule"`` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler.

        :schema: io.k8s.api.core.v1.Taint#effect
        '''
        result = self._values.get("effect")
        assert result is not None, "Required property 'effect' is missing"
        return typing.cast(IoK8SApiCoreV1TaintEffect, result)

    @builtins.property
    def key(self) -> builtins.str:
        '''Required.

        The taint key to be applied to a node.

        :schema: io.k8s.api.core.v1.Taint#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def time_added(self) -> typing.Optional[datetime.datetime]:
        '''TimeAdded represents the time at which the taint was added.

        It is only written for NoExecute taints.

        :schema: io.k8s.api.core.v1.Taint#timeAdded
        '''
        result = self._values.get("time_added")
        return typing.cast(typing.Optional[datetime.datetime], result)

    @builtins.property
    def value(self) -> typing.Optional[builtins.str]:
        '''The taint value corresponding to the taint key.

        :schema: io.k8s.api.core.v1.Taint#value
        '''
        result = self._values.get("value")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Taint(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TcpSocketAction",
    jsii_struct_bases=[],
    name_mapping={"port": "port", "host": "host"},
)
class TcpSocketAction:
    def __init__(
        self,
        *,
        port: IntOrString,
        host: typing.Optional[builtins.str] = None,
    ) -> None:
        '''TCPSocketAction describes an action based on opening a socket.

        :param port: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.
        :param host: Optional: Host name to connect to, defaults to the pod IP.

        :schema: io.k8s.api.core.v1.TCPSocketAction
        '''
        if __debug__:
            def stub(
                *,
                port: IntOrString,
                host: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument host", value=host, expected_type=type_hints["host"])
        self._values: typing.Dict[str, typing.Any] = {
            "port": port,
        }
        if host is not None:
            self._values["host"] = host

    @builtins.property
    def port(self) -> IntOrString:
        '''Number or name of the port to access on the container.

        Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.

        :schema: io.k8s.api.core.v1.TCPSocketAction#port
        '''
        result = self._values.get("port")
        assert result is not None, "Required property 'port' is missing"
        return typing.cast(IntOrString, result)

    @builtins.property
    def host(self) -> typing.Optional[builtins.str]:
        '''Optional: Host name to connect to, defaults to the pod IP.

        :schema: io.k8s.api.core.v1.TCPSocketAction#host
        '''
        result = self._values.get("host")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TcpSocketAction(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TokenRequest",
    jsii_struct_bases=[],
    name_mapping={"audience": "audience", "expiration_seconds": "expirationSeconds"},
)
class TokenRequest:
    def __init__(
        self,
        *,
        audience: builtins.str,
        expiration_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''TokenRequest contains parameters of a service account token.

        :param audience: Audience is the intended audience of the token in "TokenRequestSpec". It will default to the audiences of kube apiserver.
        :param expiration_seconds: ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". It has the same default value of "ExpirationSeconds" in "TokenRequestSpec".

        :schema: io.k8s.api.storage.v1.TokenRequest
        '''
        if __debug__:
            def stub(
                *,
                audience: builtins.str,
                expiration_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument audience", value=audience, expected_type=type_hints["audience"])
            check_type(argname="argument expiration_seconds", value=expiration_seconds, expected_type=type_hints["expiration_seconds"])
        self._values: typing.Dict[str, typing.Any] = {
            "audience": audience,
        }
        if expiration_seconds is not None:
            self._values["expiration_seconds"] = expiration_seconds

    @builtins.property
    def audience(self) -> builtins.str:
        '''Audience is the intended audience of the token in "TokenRequestSpec".

        It will default to the audiences of kube apiserver.

        :schema: io.k8s.api.storage.v1.TokenRequest#audience
        '''
        result = self._values.get("audience")
        assert result is not None, "Required property 'audience' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def expiration_seconds(self) -> typing.Optional[jsii.Number]:
        '''ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec".

        It has the same default value of "ExpirationSeconds" in "TokenRequestSpec".

        :schema: io.k8s.api.storage.v1.TokenRequest#expirationSeconds
        '''
        result = self._values.get("expiration_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TokenRequest(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TokenRequestSpec",
    jsii_struct_bases=[],
    name_mapping={
        "audiences": "audiences",
        "bound_object_ref": "boundObjectRef",
        "expiration_seconds": "expirationSeconds",
    },
)
class TokenRequestSpec:
    def __init__(
        self,
        *,
        audiences: typing.Sequence[builtins.str],
        bound_object_ref: typing.Optional[typing.Union[BoundObjectReference, typing.Dict[str, typing.Any]]] = None,
        expiration_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''TokenRequestSpec contains client provided parameters of a token request.

        :param audiences: Audiences are the intendend audiences of the token. A recipient of a token must identitfy themself with an identifier in the list of audiences of the token, and otherwise should reject the token. A token issued for multiple audiences may be used to authenticate against any of the audiences listed but implies a high degree of trust between the target audiences.
        :param bound_object_ref: BoundObjectRef is a reference to an object that the token will be bound to. The token will only be valid for as long as the bound object exists. NOTE: The API server's TokenReview endpoint will validate the BoundObjectRef, but other audiences may not. Keep ExpirationSeconds small if you want prompt revocation.
        :param expiration_seconds: ExpirationSeconds is the requested duration of validity of the request. The token issuer may return a token with a different validity duration so a client needs to check the 'expiration' field in a response.

        :schema: io.k8s.api.authentication.v1.TokenRequestSpec
        '''
        if isinstance(bound_object_ref, dict):
            bound_object_ref = BoundObjectReference(**bound_object_ref)
        if __debug__:
            def stub(
                *,
                audiences: typing.Sequence[builtins.str],
                bound_object_ref: typing.Optional[typing.Union[BoundObjectReference, typing.Dict[str, typing.Any]]] = None,
                expiration_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument audiences", value=audiences, expected_type=type_hints["audiences"])
            check_type(argname="argument bound_object_ref", value=bound_object_ref, expected_type=type_hints["bound_object_ref"])
            check_type(argname="argument expiration_seconds", value=expiration_seconds, expected_type=type_hints["expiration_seconds"])
        self._values: typing.Dict[str, typing.Any] = {
            "audiences": audiences,
        }
        if bound_object_ref is not None:
            self._values["bound_object_ref"] = bound_object_ref
        if expiration_seconds is not None:
            self._values["expiration_seconds"] = expiration_seconds

    @builtins.property
    def audiences(self) -> typing.List[builtins.str]:
        '''Audiences are the intendend audiences of the token.

        A recipient of a token must identitfy themself with an identifier in the list of audiences of the token, and otherwise should reject the token. A token issued for multiple audiences may be used to authenticate against any of the audiences listed but implies a high degree of trust between the target audiences.

        :schema: io.k8s.api.authentication.v1.TokenRequestSpec#audiences
        '''
        result = self._values.get("audiences")
        assert result is not None, "Required property 'audiences' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def bound_object_ref(self) -> typing.Optional[BoundObjectReference]:
        '''BoundObjectRef is a reference to an object that the token will be bound to.

        The token will only be valid for as long as the bound object exists. NOTE: The API server's TokenReview endpoint will validate the BoundObjectRef, but other audiences may not. Keep ExpirationSeconds small if you want prompt revocation.

        :schema: io.k8s.api.authentication.v1.TokenRequestSpec#boundObjectRef
        '''
        result = self._values.get("bound_object_ref")
        return typing.cast(typing.Optional[BoundObjectReference], result)

    @builtins.property
    def expiration_seconds(self) -> typing.Optional[jsii.Number]:
        '''ExpirationSeconds is the requested duration of validity of the request.

        The token issuer may return a token with a different validity duration so a client needs to check the 'expiration' field in a response.

        :schema: io.k8s.api.authentication.v1.TokenRequestSpec#expirationSeconds
        '''
        result = self._values.get("expiration_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TokenRequestSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TokenReviewSpec",
    jsii_struct_bases=[],
    name_mapping={"audiences": "audiences", "token": "token"},
)
class TokenReviewSpec:
    def __init__(
        self,
        *,
        audiences: typing.Optional[typing.Sequence[builtins.str]] = None,
        token: typing.Optional[builtins.str] = None,
    ) -> None:
        '''TokenReviewSpec is a description of the token authentication request.

        :param audiences: Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.
        :param token: Token is the opaque bearer token.

        :schema: io.k8s.api.authentication.v1.TokenReviewSpec
        '''
        if __debug__:
            def stub(
                *,
                audiences: typing.Optional[typing.Sequence[builtins.str]] = None,
                token: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument audiences", value=audiences, expected_type=type_hints["audiences"])
            check_type(argname="argument token", value=token, expected_type=type_hints["token"])
        self._values: typing.Dict[str, typing.Any] = {}
        if audiences is not None:
            self._values["audiences"] = audiences
        if token is not None:
            self._values["token"] = token

    @builtins.property
    def audiences(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Audiences is a list of the identifiers that the resource server presented with the token identifies as.

        Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.

        :schema: io.k8s.api.authentication.v1.TokenReviewSpec#audiences
        '''
        result = self._values.get("audiences")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def token(self) -> typing.Optional[builtins.str]:
        '''Token is the opaque bearer token.

        :schema: io.k8s.api.authentication.v1.TokenReviewSpec#token
        '''
        result = self._values.get("token")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TokenReviewSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Toleration",
    jsii_struct_bases=[],
    name_mapping={
        "effect": "effect",
        "key": "key",
        "operator": "operator",
        "toleration_seconds": "tolerationSeconds",
        "value": "value",
    },
)
class Toleration:
    def __init__(
        self,
        *,
        effect: typing.Optional[IoK8SApiCoreV1TolerationEffect] = None,
        key: typing.Optional[builtins.str] = None,
        operator: typing.Optional[IoK8SApiCoreV1TolerationOperator] = None,
        toleration_seconds: typing.Optional[jsii.Number] = None,
        value: typing.Optional[builtins.str] = None,
    ) -> None:
        '''The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator .

        :param effect: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. Possible enum values: - ``"NoExecute"`` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController. - ``"NoSchedule"`` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler. - ``"PreferNoSchedule"`` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler.
        :param key: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.
        :param operator: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. Possible enum values: - ``"Equal"`` - ``"Exists"`` Default: Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.
        :param toleration_seconds: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.
        :param value: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.

        :schema: io.k8s.api.core.v1.Toleration
        '''
        if __debug__:
            def stub(
                *,
                effect: typing.Optional[IoK8SApiCoreV1TolerationEffect] = None,
                key: typing.Optional[builtins.str] = None,
                operator: typing.Optional[IoK8SApiCoreV1TolerationOperator] = None,
                toleration_seconds: typing.Optional[jsii.Number] = None,
                value: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument effect", value=effect, expected_type=type_hints["effect"])
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument operator", value=operator, expected_type=type_hints["operator"])
            check_type(argname="argument toleration_seconds", value=toleration_seconds, expected_type=type_hints["toleration_seconds"])
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        self._values: typing.Dict[str, typing.Any] = {}
        if effect is not None:
            self._values["effect"] = effect
        if key is not None:
            self._values["key"] = key
        if operator is not None:
            self._values["operator"] = operator
        if toleration_seconds is not None:
            self._values["toleration_seconds"] = toleration_seconds
        if value is not None:
            self._values["value"] = value

    @builtins.property
    def effect(self) -> typing.Optional[IoK8SApiCoreV1TolerationEffect]:
        '''Effect indicates the taint effect to match.

        Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

        Possible enum values:

        - ``"NoExecute"`` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController.
        - ``"NoSchedule"`` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler.
        - ``"PreferNoSchedule"`` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler.

        :schema: io.k8s.api.core.v1.Toleration#effect
        '''
        result = self._values.get("effect")
        return typing.cast(typing.Optional[IoK8SApiCoreV1TolerationEffect], result)

    @builtins.property
    def key(self) -> typing.Optional[builtins.str]:
        '''Key is the taint key that the toleration applies to.

        Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.

        :schema: io.k8s.api.core.v1.Toleration#key
        '''
        result = self._values.get("key")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def operator(self) -> typing.Optional[IoK8SApiCoreV1TolerationOperator]:
        '''Operator represents a key's relationship to the value.

        Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

        Possible enum values:

        - ``"Equal"``
        - ``"Exists"``

        :default: Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

        :schema: io.k8s.api.core.v1.Toleration#operator
        '''
        result = self._values.get("operator")
        return typing.cast(typing.Optional[IoK8SApiCoreV1TolerationOperator], result)

    @builtins.property
    def toleration_seconds(self) -> typing.Optional[jsii.Number]:
        '''TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint.

        By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.

        :schema: io.k8s.api.core.v1.Toleration#tolerationSeconds
        '''
        result = self._values.get("toleration_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def value(self) -> typing.Optional[builtins.str]:
        '''Value is the taint value the toleration matches to.

        If the operator is Exists, the value should be empty, otherwise just a regular string.

        :schema: io.k8s.api.core.v1.Toleration#value
        '''
        result = self._values.get("value")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Toleration(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TopologySelectorLabelRequirement",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "values": "values"},
)
class TopologySelectorLabelRequirement:
    def __init__(
        self,
        *,
        key: builtins.str,
        values: typing.Sequence[builtins.str],
    ) -> None:
        '''A topology selector requirement is a selector that matches given label.

        This is an alpha feature and may change in the future.

        :param key: The label key that the selector applies to.
        :param values: An array of string values. One value must match the label to be selected. Each entry in Values is ORed.

        :schema: io.k8s.api.core.v1.TopologySelectorLabelRequirement
        '''
        if __debug__:
            def stub(
                *,
                key: builtins.str,
                values: typing.Sequence[builtins.str],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument key", value=key, expected_type=type_hints["key"])
            check_type(argname="argument values", value=values, expected_type=type_hints["values"])
        self._values: typing.Dict[str, typing.Any] = {
            "key": key,
            "values": values,
        }

    @builtins.property
    def key(self) -> builtins.str:
        '''The label key that the selector applies to.

        :schema: io.k8s.api.core.v1.TopologySelectorLabelRequirement#key
        '''
        result = self._values.get("key")
        assert result is not None, "Required property 'key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def values(self) -> typing.List[builtins.str]:
        '''An array of string values.

        One value must match the label to be selected. Each entry in Values is ORed.

        :schema: io.k8s.api.core.v1.TopologySelectorLabelRequirement#values
        '''
        result = self._values.get("values")
        assert result is not None, "Required property 'values' is missing"
        return typing.cast(typing.List[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TopologySelectorLabelRequirement(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TopologySelectorTerm",
    jsii_struct_bases=[],
    name_mapping={"match_label_expressions": "matchLabelExpressions"},
)
class TopologySelectorTerm:
    def __init__(
        self,
        *,
        match_label_expressions: typing.Optional[typing.Sequence[typing.Union[TopologySelectorLabelRequirement, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''A topology selector term represents the result of label queries.

        A null or empty topology selector term matches no objects. The requirements of them are ANDed. It provides a subset of functionality as NodeSelectorTerm. This is an alpha feature and may change in the future.

        :param match_label_expressions: A list of topology selector requirements by labels.

        :schema: io.k8s.api.core.v1.TopologySelectorTerm
        '''
        if __debug__:
            def stub(
                *,
                match_label_expressions: typing.Optional[typing.Sequence[typing.Union[TopologySelectorLabelRequirement, typing.Dict[str, typing.Any]]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument match_label_expressions", value=match_label_expressions, expected_type=type_hints["match_label_expressions"])
        self._values: typing.Dict[str, typing.Any] = {}
        if match_label_expressions is not None:
            self._values["match_label_expressions"] = match_label_expressions

    @builtins.property
    def match_label_expressions(
        self,
    ) -> typing.Optional[typing.List[TopologySelectorLabelRequirement]]:
        '''A list of topology selector requirements by labels.

        :schema: io.k8s.api.core.v1.TopologySelectorTerm#matchLabelExpressions
        '''
        result = self._values.get("match_label_expressions")
        return typing.cast(typing.Optional[typing.List[TopologySelectorLabelRequirement]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TopologySelectorTerm(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TopologySpreadConstraint",
    jsii_struct_bases=[],
    name_mapping={
        "max_skew": "maxSkew",
        "topology_key": "topologyKey",
        "when_unsatisfiable": "whenUnsatisfiable",
        "label_selector": "labelSelector",
    },
)
class TopologySpreadConstraint:
    def __init__(
        self,
        *,
        max_skew: jsii.Number,
        topology_key: builtins.str,
        when_unsatisfiable: IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable,
        label_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''TopologySpreadConstraint specifies how to spread matching pods among the given topology.

        :param max_skew: 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 topology_key: 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 <key, value> as a "bucket", and try to put balanced number of pods into each bucket. It's a required field.
        :param when_unsatisfiable: 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 assignment 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. Possible enum values: - ``"DoNotSchedule"`` instructs the scheduler not to schedule the pod when constraints are not satisfied. - ``"ScheduleAnyway"`` instructs the scheduler to schedule the pod even if constraints are not satisfied.
        :param label_selector: 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.

        :schema: io.k8s.api.core.v1.TopologySpreadConstraint
        '''
        if isinstance(label_selector, dict):
            label_selector = LabelSelector(**label_selector)
        if __debug__:
            def stub(
                *,
                max_skew: jsii.Number,
                topology_key: builtins.str,
                when_unsatisfiable: IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable,
                label_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument max_skew", value=max_skew, expected_type=type_hints["max_skew"])
            check_type(argname="argument topology_key", value=topology_key, expected_type=type_hints["topology_key"])
            check_type(argname="argument when_unsatisfiable", value=when_unsatisfiable, expected_type=type_hints["when_unsatisfiable"])
            check_type(argname="argument label_selector", value=label_selector, expected_type=type_hints["label_selector"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_skew": max_skew,
            "topology_key": topology_key,
            "when_unsatisfiable": when_unsatisfiable,
        }
        if label_selector is not None:
            self._values["label_selector"] = label_selector

    @builtins.property
    def max_skew(self) -> jsii.Number:
        '''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.

        :schema: io.k8s.api.core.v1.TopologySpreadConstraint#maxSkew
        '''
        result = self._values.get("max_skew")
        assert result is not None, "Required property 'max_skew' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def topology_key(self) -> builtins.str:
        '''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 <key, value> as a "bucket", and try to put balanced number of pods into each bucket. It's a required field.

        :schema: io.k8s.api.core.v1.TopologySpreadConstraint#topologyKey
        '''
        result = self._values.get("topology_key")
        assert result is not None, "Required property 'topology_key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def when_unsatisfiable(
        self,
    ) -> IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable:
        '''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 assignment 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.

        Possible enum values:

        - ``"DoNotSchedule"`` instructs the scheduler not to schedule the pod when constraints are not satisfied.
        - ``"ScheduleAnyway"`` instructs the scheduler to schedule the pod even if constraints are not satisfied.

        :schema: io.k8s.api.core.v1.TopologySpreadConstraint#whenUnsatisfiable
        '''
        result = self._values.get("when_unsatisfiable")
        assert result is not None, "Required property 'when_unsatisfiable' is missing"
        return typing.cast(IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable, result)

    @builtins.property
    def label_selector(self) -> typing.Optional[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.

        :schema: io.k8s.api.core.v1.TopologySpreadConstraint#labelSelector
        '''
        result = self._values.get("label_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TopologySpreadConstraint(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.TypedLocalObjectReference",
    jsii_struct_bases=[],
    name_mapping={"kind": "kind", "name": "name", "api_group": "apiGroup"},
)
class TypedLocalObjectReference:
    def __init__(
        self,
        *,
        kind: builtins.str,
        name: builtins.str,
        api_group: typing.Optional[builtins.str] = None,
    ) -> None:
        '''TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace.

        :param kind: Kind is the type of resource being referenced.
        :param name: Name is the name of resource being referenced.
        :param api_group: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

        :schema: io.k8s.api.core.v1.TypedLocalObjectReference
        '''
        if __debug__:
            def stub(
                *,
                kind: builtins.str,
                name: builtins.str,
                api_group: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument kind", value=kind, expected_type=type_hints["kind"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument api_group", value=api_group, expected_type=type_hints["api_group"])
        self._values: typing.Dict[str, typing.Any] = {
            "kind": kind,
            "name": name,
        }
        if api_group is not None:
            self._values["api_group"] = api_group

    @builtins.property
    def kind(self) -> builtins.str:
        '''Kind is the type of resource being referenced.

        :schema: io.k8s.api.core.v1.TypedLocalObjectReference#kind
        '''
        result = self._values.get("kind")
        assert result is not None, "Required property 'kind' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''Name is the name of resource being referenced.

        :schema: io.k8s.api.core.v1.TypedLocalObjectReference#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def api_group(self) -> typing.Optional[builtins.str]:
        '''APIGroup is the group for the resource being referenced.

        If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

        :schema: io.k8s.api.core.v1.TypedLocalObjectReference#apiGroup
        '''
        result = self._values.get("api_group")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TypedLocalObjectReference(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.UserSubjectV1Beta1",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class UserSubjectV1Beta1:
    def __init__(self, *, name: builtins.str) -> None:
        '''UserSubject holds detailed information for user-kind subject.

        :param name: ``name`` is the username that matches, or "*" to match all usernames. Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.UserSubject
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the username that matches, or "*" to match all usernames.

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta1.UserSubject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "UserSubjectV1Beta1(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.UserSubjectV1Beta2",
    jsii_struct_bases=[],
    name_mapping={"name": "name"},
)
class UserSubjectV1Beta2:
    def __init__(self, *, name: builtins.str) -> None:
        '''UserSubject holds detailed information for user-kind subject.

        :param name: ``name`` is the username that matches, or "*" to match all usernames. Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.UserSubject
        '''
        if __debug__:
            def stub(*, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }

    @builtins.property
    def name(self) -> builtins.str:
        '''``name`` is the username that matches, or "*" to match all usernames.

        Required.

        :schema: io.k8s.api.flowcontrol.v1beta2.UserSubject#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "UserSubjectV1Beta2(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ValidatingWebhook",
    jsii_struct_bases=[],
    name_mapping={
        "admission_review_versions": "admissionReviewVersions",
        "client_config": "clientConfig",
        "name": "name",
        "side_effects": "sideEffects",
        "failure_policy": "failurePolicy",
        "match_policy": "matchPolicy",
        "namespace_selector": "namespaceSelector",
        "object_selector": "objectSelector",
        "rules": "rules",
        "timeout_seconds": "timeoutSeconds",
    },
)
class ValidatingWebhook:
    def __init__(
        self,
        *,
        admission_review_versions: typing.Sequence[builtins.str],
        client_config: typing.Union["WebhookClientConfig", typing.Dict[str, typing.Any]],
        name: builtins.str,
        side_effects: builtins.str,
        failure_policy: typing.Optional[builtins.str] = None,
        match_policy: typing.Optional[builtins.str] = None,
        namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        object_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
        rules: typing.Optional[typing.Sequence[typing.Union[RuleWithOperations, typing.Dict[str, typing.Any]]]] = None,
        timeout_seconds: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''ValidatingWebhook describes an admission webhook and the resources and operations it applies to.

        :param admission_review_versions: 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 client_config: ClientConfig defines how to communicate with the hook. Required
        :param 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 side_effects: 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 failure_policy: FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail. Default: Fail.
        :param match_policy: 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" Default: Equivalent"
        :param namespace_selector: 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. Default: the empty LabelSelector, which matches everything.
        :param object_selector: 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. Default: the empty LabelSelector, which matches everything.
        :param 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 timeout_seconds: 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. Default: 10 seconds.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook
        '''
        if isinstance(client_config, dict):
            client_config = WebhookClientConfig(**client_config)
        if isinstance(namespace_selector, dict):
            namespace_selector = LabelSelector(**namespace_selector)
        if isinstance(object_selector, dict):
            object_selector = LabelSelector(**object_selector)
        if __debug__:
            def stub(
                *,
                admission_review_versions: typing.Sequence[builtins.str],
                client_config: typing.Union[WebhookClientConfig, typing.Dict[str, typing.Any]],
                name: builtins.str,
                side_effects: builtins.str,
                failure_policy: typing.Optional[builtins.str] = None,
                match_policy: typing.Optional[builtins.str] = None,
                namespace_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                object_selector: typing.Optional[typing.Union[LabelSelector, typing.Dict[str, typing.Any]]] = None,
                rules: typing.Optional[typing.Sequence[typing.Union[RuleWithOperations, typing.Dict[str, typing.Any]]]] = None,
                timeout_seconds: typing.Optional[jsii.Number] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument admission_review_versions", value=admission_review_versions, expected_type=type_hints["admission_review_versions"])
            check_type(argname="argument client_config", value=client_config, expected_type=type_hints["client_config"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument side_effects", value=side_effects, expected_type=type_hints["side_effects"])
            check_type(argname="argument failure_policy", value=failure_policy, expected_type=type_hints["failure_policy"])
            check_type(argname="argument match_policy", value=match_policy, expected_type=type_hints["match_policy"])
            check_type(argname="argument namespace_selector", value=namespace_selector, expected_type=type_hints["namespace_selector"])
            check_type(argname="argument object_selector", value=object_selector, expected_type=type_hints["object_selector"])
            check_type(argname="argument rules", value=rules, expected_type=type_hints["rules"])
            check_type(argname="argument timeout_seconds", value=timeout_seconds, expected_type=type_hints["timeout_seconds"])
        self._values: typing.Dict[str, typing.Any] = {
            "admission_review_versions": admission_review_versions,
            "client_config": client_config,
            "name": name,
            "side_effects": side_effects,
        }
        if failure_policy is not None:
            self._values["failure_policy"] = failure_policy
        if match_policy is not None:
            self._values["match_policy"] = match_policy
        if namespace_selector is not None:
            self._values["namespace_selector"] = namespace_selector
        if object_selector is not None:
            self._values["object_selector"] = object_selector
        if rules is not None:
            self._values["rules"] = rules
        if timeout_seconds is not None:
            self._values["timeout_seconds"] = timeout_seconds

    @builtins.property
    def admission_review_versions(self) -> typing.List[builtins.str]:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#admissionReviewVersions
        '''
        result = self._values.get("admission_review_versions")
        assert result is not None, "Required property 'admission_review_versions' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def client_config(self) -> "WebhookClientConfig":
        '''ClientConfig defines how to communicate with the hook.

        Required

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#clientConfig
        '''
        result = self._values.get("client_config")
        assert result is not None, "Required property 'client_config' is missing"
        return typing.cast("WebhookClientConfig", result)

    @builtins.property
    def name(self) -> builtins.str:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def side_effects(self) -> builtins.str:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#sideEffects
        '''
        result = self._values.get("side_effects")
        assert result is not None, "Required property 'side_effects' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def failure_policy(self) -> typing.Optional[builtins.str]:
        '''FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail.

        Defaults to Fail.

        :default: Fail.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#failurePolicy
        '''
        result = self._values.get("failure_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def match_policy(self) -> typing.Optional[builtins.str]:
        '''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"

        :default: Equivalent"

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#matchPolicy
        '''
        result = self._values.get("match_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def namespace_selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :default: the empty LabelSelector, which matches everything.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#namespaceSelector
        '''
        result = self._values.get("namespace_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def object_selector(self) -> typing.Optional[LabelSelector]:
        '''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.

        :default: the empty LabelSelector, which matches everything.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#objectSelector
        '''
        result = self._values.get("object_selector")
        return typing.cast(typing.Optional[LabelSelector], result)

    @builtins.property
    def rules(self) -> typing.Optional[typing.List[RuleWithOperations]]:
        '''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.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#rules
        '''
        result = self._values.get("rules")
        return typing.cast(typing.Optional[typing.List[RuleWithOperations]], result)

    @builtins.property
    def timeout_seconds(self) -> typing.Optional[jsii.Number]:
        '''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.

        :default: 10 seconds.

        :schema: io.k8s.api.admissionregistration.v1.ValidatingWebhook#timeoutSeconds
        '''
        result = self._values.get("timeout_seconds")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ValidatingWebhook(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.ValidationRule",
    jsii_struct_bases=[],
    name_mapping={"rule": "rule", "message": "message"},
)
class ValidationRule:
    def __init__(
        self,
        *,
        rule: builtins.str,
        message: typing.Optional[builtins.str] = None,
    ) -> None:
        '''ValidationRule describes a validation rule written in the CEL expression language.

        :param rule: Rule represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec The Rule is scoped to the location of the x-kubernetes-validations extension in the schema. The ``self`` variable in the CEL expression is bound to the scoped value. Example: - Rule scoped to the root of a resource with a status subresource: {"rule": "self.status.actual <= self.spec.maxDesired"} If the Rule is scoped to an object with properties, the accessible properties of the object are field selectable via ``self.field`` and field presence can be checked via ``has(self.field)``. Null valued fields are treated as absent fields in CEL expressions. If the Rule is scoped to an object with additionalProperties (i.e. a map) the value of the map are accessible via ``self[mapKey]``, map containment can be checked via ``mapKey in self`` and all entries of the map are accessible via CEL macros and functions such as ``self.all(...)``. If the Rule is scoped to an array, the elements of the array are accessible via ``self[i]`` and also by macros and functions. If the Rule is scoped to a scalar, ``self`` is bound to the scalar value. Examples: - Rule scoped to a map of objects: {"rule": "self.components['Widget'].priority < 10"} - Rule scoped to a list of integers: {"rule": "self.values.all(value, value >= 0 && value < 100)"} - Rule scoped to a string value: {"rule": "self.startsWith('kube')"} The ``apiVersion``, ``kind``, ``metadata.name`` and ``metadata.generateName`` are always accessible from the root of the object and from any x-kubernetes-embedded-resource annotated objects. No other metadata properties are accessible. Unknown data preserved in custom resources via x-kubernetes-preserve-unknown-fields is not accessible in CEL expressions. This includes: - Unknown field values that are preserved by object schemas with x-kubernetes-preserve-unknown-fields. - Object properties where the property schema is of an "unknown type". An "unknown type" is recursively defined as: - A schema with no type and x-kubernetes-preserve-unknown-fields set to true - An array where the items schema is of an "unknown type" - An object where the additionalProperties schema is of an "unknown type" Only property names of the form ``[a-zA-Z_.-/][a-zA-Z0-9_.-/]*`` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '**' escapes to '**underscores**' - '.' escapes to '**dot**' - '-' escapes to '**dash**' - '/' escapes to '**slash**' - Property names that exactly match a CEL RESERVED keyword escape to '**{keyword}__'. The keywords are: "true", "false", "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if", "import", "let", "loop", "package", "namespace", "return". Examples: - Rule accessing a property named "namespace": {"rule": "self.**namespace** > 0"} - Rule accessing a property named "x-prop": {"rule": "self.x__dash__prop > 0"} - Rule accessing a property named "redact__d": {"rule": "self.redact__underscores__d > 0"} Equality on arrays with x-kubernetes-list-type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type: - 'set': ``X + Y`` performs a union where the array positions of all elements in ``X`` are preserved and non-intersecting elements in ``Y`` are appended, retaining their partial order. - 'map': ``X + Y`` performs a merge where the array positions of all keys in ``X`` are preserved but the values are overwritten by values in ``Y`` when the key sets of ``X`` and ``Y`` intersect. Elements in ``Y`` with non-intersecting keys are appended, retaining their partial order.
        :param message: Message represents the message displayed when validation fails. The message is required if the Rule contains line breaks. The message must not contain line breaks. If unset, the message is "failed rule: {Rule}". e.g. "must be a URL with the host matching spec.host"

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ValidationRule
        '''
        if __debug__:
            def stub(
                *,
                rule: builtins.str,
                message: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument rule", value=rule, expected_type=type_hints["rule"])
            check_type(argname="argument message", value=message, expected_type=type_hints["message"])
        self._values: typing.Dict[str, typing.Any] = {
            "rule": rule,
        }
        if message is not None:
            self._values["message"] = message

    @builtins.property
    def rule(self) -> builtins.str:
        '''Rule represents the expression which will be evaluated by CEL.

        ref: https://github.com/google/cel-spec The Rule is scoped to the location of the x-kubernetes-validations extension in the schema. The ``self`` variable in the CEL expression is bound to the scoped value. Example: - Rule scoped to the root of a resource with a status subresource: {"rule": "self.status.actual <= self.spec.maxDesired"}

        If the Rule is scoped to an object with properties, the accessible properties of the object are field selectable via ``self.field`` and field presence can be checked via ``has(self.field)``. Null valued fields are treated as absent fields in CEL expressions. If the Rule is scoped to an object with additionalProperties (i.e. a map) the value of the map are accessible via ``self[mapKey]``, map containment can be checked via ``mapKey in self`` and all entries of the map are accessible via CEL macros and functions such as ``self.all(...)``. If the Rule is scoped to an array, the elements of the array are accessible via ``self[i]`` and also by macros and functions. If the Rule is scoped to a scalar, ``self`` is bound to the scalar value. Examples: - Rule scoped to a map of objects: {"rule": "self.components['Widget'].priority < 10"} - Rule scoped to a list of integers: {"rule": "self.values.all(value, value >= 0 && value < 100)"} - Rule scoped to a string value: {"rule": "self.startsWith('kube')"}

        The ``apiVersion``, ``kind``, ``metadata.name`` and ``metadata.generateName`` are always accessible from the root of the object and from any x-kubernetes-embedded-resource annotated objects. No other metadata properties are accessible.

        Unknown data preserved in custom resources via x-kubernetes-preserve-unknown-fields is not accessible in CEL expressions. This includes: - Unknown field values that are preserved by object schemas with x-kubernetes-preserve-unknown-fields. - Object properties where the property schema is of an "unknown type". An "unknown type" is recursively defined as:

        - A schema with no type and x-kubernetes-preserve-unknown-fields set to true
        - An array where the items schema is of an "unknown type"
        - An object where the additionalProperties schema is of an "unknown type"

        Only property names of the form ``[a-zA-Z_.-/][a-zA-Z0-9_.-/]*`` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '**' escapes to '**underscores**' - '.' escapes to '**dot**' - '-' escapes to '**dash**' - '/' escapes to '**slash**' - Property names that exactly match a CEL RESERVED keyword escape to '**{keyword}__'. The keywords are:
        "true", "false", "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if",
        "import", "let", "loop", "package", "namespace", "return".
        Examples:

        - Rule accessing a property named "namespace": {"rule": "self.**namespace** > 0"}
        - Rule accessing a property named "x-prop": {"rule": "self.x__dash__prop > 0"}
        - Rule accessing a property named "redact__d": {"rule": "self.redact__underscores__d > 0"}

        Equality on arrays with x-kubernetes-list-type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:

        - 'set': ``X + Y`` performs a union where the array positions of all elements in ``X`` are preserved and
          non-intersecting elements in ``Y`` are appended, retaining their partial order.
        - 'map': ``X + Y`` performs a merge where the array positions of all keys in ``X`` are preserved but the values
          are overwritten by values in ``Y`` when the key sets of ``X`` and ``Y`` intersect. Elements in ``Y`` with
          non-intersecting keys are appended, retaining their partial order.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ValidationRule#rule
        '''
        result = self._values.get("rule")
        assert result is not None, "Required property 'rule' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def message(self) -> typing.Optional[builtins.str]:
        '''Message represents the message displayed when validation fails.

        The message is required if the Rule contains line breaks. The message must not contain line breaks. If unset, the message is "failed rule: {Rule}". e.g. "must be a URL with the host matching spec.host"

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ValidationRule#message
        '''
        result = self._values.get("message")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ValidationRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.Volume",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "aws_elastic_block_store": "awsElasticBlockStore",
        "azure_disk": "azureDisk",
        "azure_file": "azureFile",
        "cephfs": "cephfs",
        "cinder": "cinder",
        "config_map": "configMap",
        "csi": "csi",
        "downward_api": "downwardApi",
        "empty_dir": "emptyDir",
        "ephemeral": "ephemeral",
        "fc": "fc",
        "flex_volume": "flexVolume",
        "flocker": "flocker",
        "gce_persistent_disk": "gcePersistentDisk",
        "git_repo": "gitRepo",
        "glusterfs": "glusterfs",
        "host_path": "hostPath",
        "iscsi": "iscsi",
        "nfs": "nfs",
        "persistent_volume_claim": "persistentVolumeClaim",
        "photon_persistent_disk": "photonPersistentDisk",
        "portworx_volume": "portworxVolume",
        "projected": "projected",
        "quobyte": "quobyte",
        "rbd": "rbd",
        "scale_io": "scaleIo",
        "secret": "secret",
        "storageos": "storageos",
        "vsphere_volume": "vsphereVolume",
    },
)
class Volume:
    def __init__(
        self,
        *,
        name: builtins.str,
        aws_elastic_block_store: typing.Optional[typing.Union[AwsElasticBlockStoreVolumeSource, typing.Dict[str, typing.Any]]] = None,
        azure_disk: typing.Optional[typing.Union[AzureDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
        azure_file: typing.Optional[typing.Union[AzureFileVolumeSource, typing.Dict[str, typing.Any]]] = None,
        cephfs: typing.Optional[typing.Union[CephFsVolumeSource, typing.Dict[str, typing.Any]]] = None,
        cinder: typing.Optional[typing.Union[CinderVolumeSource, typing.Dict[str, typing.Any]]] = None,
        config_map: typing.Optional[typing.Union[ConfigMapVolumeSource, typing.Dict[str, typing.Any]]] = None,
        csi: typing.Optional[typing.Union[CsiVolumeSource, typing.Dict[str, typing.Any]]] = None,
        downward_api: typing.Optional[typing.Union[DownwardApiVolumeSource, typing.Dict[str, typing.Any]]] = None,
        empty_dir: typing.Optional[typing.Union[EmptyDirVolumeSource, typing.Dict[str, typing.Any]]] = None,
        ephemeral: typing.Optional[typing.Union[EphemeralVolumeSource, typing.Dict[str, typing.Any]]] = None,
        fc: typing.Optional[typing.Union[FcVolumeSource, typing.Dict[str, typing.Any]]] = None,
        flex_volume: typing.Optional[typing.Union[FlexVolumeSource, typing.Dict[str, typing.Any]]] = None,
        flocker: typing.Optional[typing.Union[FlockerVolumeSource, typing.Dict[str, typing.Any]]] = None,
        gce_persistent_disk: typing.Optional[typing.Union[GcePersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
        git_repo: typing.Optional[typing.Union[GitRepoVolumeSource, typing.Dict[str, typing.Any]]] = None,
        glusterfs: typing.Optional[typing.Union[GlusterfsVolumeSource, typing.Dict[str, typing.Any]]] = None,
        host_path: typing.Optional[typing.Union[HostPathVolumeSource, typing.Dict[str, typing.Any]]] = None,
        iscsi: typing.Optional[typing.Union[IscsiVolumeSource, typing.Dict[str, typing.Any]]] = None,
        nfs: typing.Optional[typing.Union[NfsVolumeSource, typing.Dict[str, typing.Any]]] = None,
        persistent_volume_claim: typing.Optional[typing.Union[PersistentVolumeClaimVolumeSource, typing.Dict[str, typing.Any]]] = None,
        photon_persistent_disk: typing.Optional[typing.Union[PhotonPersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
        portworx_volume: typing.Optional[typing.Union[PortworxVolumeSource, typing.Dict[str, typing.Any]]] = None,
        projected: typing.Optional[typing.Union[ProjectedVolumeSource, typing.Dict[str, typing.Any]]] = None,
        quobyte: typing.Optional[typing.Union[QuobyteVolumeSource, typing.Dict[str, typing.Any]]] = None,
        rbd: typing.Optional[typing.Union[RbdVolumeSource, typing.Dict[str, typing.Any]]] = None,
        scale_io: typing.Optional[typing.Union[ScaleIoVolumeSource, typing.Dict[str, typing.Any]]] = None,
        secret: typing.Optional[typing.Union[SecretVolumeSource, typing.Dict[str, typing.Any]]] = None,
        storageos: typing.Optional[typing.Union[StorageOsVolumeSource, typing.Dict[str, typing.Any]]] = None,
        vsphere_volume: typing.Optional[typing.Union["VsphereVirtualDiskVolumeSource", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Volume represents a named volume in a pod that may be accessed by any container in the pod.

        :param name: Volume's name. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
        :param aws_elastic_block_store: AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
        :param azure_disk: AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
        :param azure_file: AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
        :param cephfs: CephFS represents a Ceph FS mount on the host that shares a pod's lifetime.
        :param cinder: Cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
        :param config_map: ConfigMap represents a configMap that should populate this volume.
        :param csi: CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).
        :param downward_api: DownwardAPI represents downward API about the pod that should populate this volume.
        :param empty_dir: EmptyDir represents a temporary directory that shares a pod's lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
        :param ephemeral: Ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. A pod can use both types of ephemeral volumes and persistent volumes at the same time.
        :param fc: FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.
        :param flex_volume: FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.
        :param flocker: Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running
        :param gce_persistent_disk: GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
        :param git_repo: GitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod's container.
        :param glusterfs: Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md
        :param host_path: HostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
        :param iscsi: ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md
        :param nfs: NFS represents an NFS mount on the host that shares a pod's lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs.
        :param persistent_volume_claim: PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
        :param photon_persistent_disk: PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.
        :param portworx_volume: PortworxVolume represents a portworx volume attached and mounted on kubelets host machine.
        :param projected: Items for all in one resources secrets, configmaps, and downward API.
        :param quobyte: Quobyte represents a Quobyte mount on the host that shares a pod's lifetime.
        :param rbd: RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md
        :param scale_io: ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
        :param secret: Secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret
        :param storageos: StorageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.
        :param vsphere_volume: VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.Volume
        '''
        if isinstance(aws_elastic_block_store, dict):
            aws_elastic_block_store = AwsElasticBlockStoreVolumeSource(**aws_elastic_block_store)
        if isinstance(azure_disk, dict):
            azure_disk = AzureDiskVolumeSource(**azure_disk)
        if isinstance(azure_file, dict):
            azure_file = AzureFileVolumeSource(**azure_file)
        if isinstance(cephfs, dict):
            cephfs = CephFsVolumeSource(**cephfs)
        if isinstance(cinder, dict):
            cinder = CinderVolumeSource(**cinder)
        if isinstance(config_map, dict):
            config_map = ConfigMapVolumeSource(**config_map)
        if isinstance(csi, dict):
            csi = CsiVolumeSource(**csi)
        if isinstance(downward_api, dict):
            downward_api = DownwardApiVolumeSource(**downward_api)
        if isinstance(empty_dir, dict):
            empty_dir = EmptyDirVolumeSource(**empty_dir)
        if isinstance(ephemeral, dict):
            ephemeral = EphemeralVolumeSource(**ephemeral)
        if isinstance(fc, dict):
            fc = FcVolumeSource(**fc)
        if isinstance(flex_volume, dict):
            flex_volume = FlexVolumeSource(**flex_volume)
        if isinstance(flocker, dict):
            flocker = FlockerVolumeSource(**flocker)
        if isinstance(gce_persistent_disk, dict):
            gce_persistent_disk = GcePersistentDiskVolumeSource(**gce_persistent_disk)
        if isinstance(git_repo, dict):
            git_repo = GitRepoVolumeSource(**git_repo)
        if isinstance(glusterfs, dict):
            glusterfs = GlusterfsVolumeSource(**glusterfs)
        if isinstance(host_path, dict):
            host_path = HostPathVolumeSource(**host_path)
        if isinstance(iscsi, dict):
            iscsi = IscsiVolumeSource(**iscsi)
        if isinstance(nfs, dict):
            nfs = NfsVolumeSource(**nfs)
        if isinstance(persistent_volume_claim, dict):
            persistent_volume_claim = PersistentVolumeClaimVolumeSource(**persistent_volume_claim)
        if isinstance(photon_persistent_disk, dict):
            photon_persistent_disk = PhotonPersistentDiskVolumeSource(**photon_persistent_disk)
        if isinstance(portworx_volume, dict):
            portworx_volume = PortworxVolumeSource(**portworx_volume)
        if isinstance(projected, dict):
            projected = ProjectedVolumeSource(**projected)
        if isinstance(quobyte, dict):
            quobyte = QuobyteVolumeSource(**quobyte)
        if isinstance(rbd, dict):
            rbd = RbdVolumeSource(**rbd)
        if isinstance(scale_io, dict):
            scale_io = ScaleIoVolumeSource(**scale_io)
        if isinstance(secret, dict):
            secret = SecretVolumeSource(**secret)
        if isinstance(storageos, dict):
            storageos = StorageOsVolumeSource(**storageos)
        if isinstance(vsphere_volume, dict):
            vsphere_volume = VsphereVirtualDiskVolumeSource(**vsphere_volume)
        if __debug__:
            def stub(
                *,
                name: builtins.str,
                aws_elastic_block_store: typing.Optional[typing.Union[AwsElasticBlockStoreVolumeSource, typing.Dict[str, typing.Any]]] = None,
                azure_disk: typing.Optional[typing.Union[AzureDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
                azure_file: typing.Optional[typing.Union[AzureFileVolumeSource, typing.Dict[str, typing.Any]]] = None,
                cephfs: typing.Optional[typing.Union[CephFsVolumeSource, typing.Dict[str, typing.Any]]] = None,
                cinder: typing.Optional[typing.Union[CinderVolumeSource, typing.Dict[str, typing.Any]]] = None,
                config_map: typing.Optional[typing.Union[ConfigMapVolumeSource, typing.Dict[str, typing.Any]]] = None,
                csi: typing.Optional[typing.Union[CsiVolumeSource, typing.Dict[str, typing.Any]]] = None,
                downward_api: typing.Optional[typing.Union[DownwardApiVolumeSource, typing.Dict[str, typing.Any]]] = None,
                empty_dir: typing.Optional[typing.Union[EmptyDirVolumeSource, typing.Dict[str, typing.Any]]] = None,
                ephemeral: typing.Optional[typing.Union[EphemeralVolumeSource, typing.Dict[str, typing.Any]]] = None,
                fc: typing.Optional[typing.Union[FcVolumeSource, typing.Dict[str, typing.Any]]] = None,
                flex_volume: typing.Optional[typing.Union[FlexVolumeSource, typing.Dict[str, typing.Any]]] = None,
                flocker: typing.Optional[typing.Union[FlockerVolumeSource, typing.Dict[str, typing.Any]]] = None,
                gce_persistent_disk: typing.Optional[typing.Union[GcePersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
                git_repo: typing.Optional[typing.Union[GitRepoVolumeSource, typing.Dict[str, typing.Any]]] = None,
                glusterfs: typing.Optional[typing.Union[GlusterfsVolumeSource, typing.Dict[str, typing.Any]]] = None,
                host_path: typing.Optional[typing.Union[HostPathVolumeSource, typing.Dict[str, typing.Any]]] = None,
                iscsi: typing.Optional[typing.Union[IscsiVolumeSource, typing.Dict[str, typing.Any]]] = None,
                nfs: typing.Optional[typing.Union[NfsVolumeSource, typing.Dict[str, typing.Any]]] = None,
                persistent_volume_claim: typing.Optional[typing.Union[PersistentVolumeClaimVolumeSource, typing.Dict[str, typing.Any]]] = None,
                photon_persistent_disk: typing.Optional[typing.Union[PhotonPersistentDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
                portworx_volume: typing.Optional[typing.Union[PortworxVolumeSource, typing.Dict[str, typing.Any]]] = None,
                projected: typing.Optional[typing.Union[ProjectedVolumeSource, typing.Dict[str, typing.Any]]] = None,
                quobyte: typing.Optional[typing.Union[QuobyteVolumeSource, typing.Dict[str, typing.Any]]] = None,
                rbd: typing.Optional[typing.Union[RbdVolumeSource, typing.Dict[str, typing.Any]]] = None,
                scale_io: typing.Optional[typing.Union[ScaleIoVolumeSource, typing.Dict[str, typing.Any]]] = None,
                secret: typing.Optional[typing.Union[SecretVolumeSource, typing.Dict[str, typing.Any]]] = None,
                storageos: typing.Optional[typing.Union[StorageOsVolumeSource, typing.Dict[str, typing.Any]]] = None,
                vsphere_volume: typing.Optional[typing.Union[VsphereVirtualDiskVolumeSource, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument aws_elastic_block_store", value=aws_elastic_block_store, expected_type=type_hints["aws_elastic_block_store"])
            check_type(argname="argument azure_disk", value=azure_disk, expected_type=type_hints["azure_disk"])
            check_type(argname="argument azure_file", value=azure_file, expected_type=type_hints["azure_file"])
            check_type(argname="argument cephfs", value=cephfs, expected_type=type_hints["cephfs"])
            check_type(argname="argument cinder", value=cinder, expected_type=type_hints["cinder"])
            check_type(argname="argument config_map", value=config_map, expected_type=type_hints["config_map"])
            check_type(argname="argument csi", value=csi, expected_type=type_hints["csi"])
            check_type(argname="argument downward_api", value=downward_api, expected_type=type_hints["downward_api"])
            check_type(argname="argument empty_dir", value=empty_dir, expected_type=type_hints["empty_dir"])
            check_type(argname="argument ephemeral", value=ephemeral, expected_type=type_hints["ephemeral"])
            check_type(argname="argument fc", value=fc, expected_type=type_hints["fc"])
            check_type(argname="argument flex_volume", value=flex_volume, expected_type=type_hints["flex_volume"])
            check_type(argname="argument flocker", value=flocker, expected_type=type_hints["flocker"])
            check_type(argname="argument gce_persistent_disk", value=gce_persistent_disk, expected_type=type_hints["gce_persistent_disk"])
            check_type(argname="argument git_repo", value=git_repo, expected_type=type_hints["git_repo"])
            check_type(argname="argument glusterfs", value=glusterfs, expected_type=type_hints["glusterfs"])
            check_type(argname="argument host_path", value=host_path, expected_type=type_hints["host_path"])
            check_type(argname="argument iscsi", value=iscsi, expected_type=type_hints["iscsi"])
            check_type(argname="argument nfs", value=nfs, expected_type=type_hints["nfs"])
            check_type(argname="argument persistent_volume_claim", value=persistent_volume_claim, expected_type=type_hints["persistent_volume_claim"])
            check_type(argname="argument photon_persistent_disk", value=photon_persistent_disk, expected_type=type_hints["photon_persistent_disk"])
            check_type(argname="argument portworx_volume", value=portworx_volume, expected_type=type_hints["portworx_volume"])
            check_type(argname="argument projected", value=projected, expected_type=type_hints["projected"])
            check_type(argname="argument quobyte", value=quobyte, expected_type=type_hints["quobyte"])
            check_type(argname="argument rbd", value=rbd, expected_type=type_hints["rbd"])
            check_type(argname="argument scale_io", value=scale_io, expected_type=type_hints["scale_io"])
            check_type(argname="argument secret", value=secret, expected_type=type_hints["secret"])
            check_type(argname="argument storageos", value=storageos, expected_type=type_hints["storageos"])
            check_type(argname="argument vsphere_volume", value=vsphere_volume, expected_type=type_hints["vsphere_volume"])
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if aws_elastic_block_store is not None:
            self._values["aws_elastic_block_store"] = aws_elastic_block_store
        if azure_disk is not None:
            self._values["azure_disk"] = azure_disk
        if azure_file is not None:
            self._values["azure_file"] = azure_file
        if cephfs is not None:
            self._values["cephfs"] = cephfs
        if cinder is not None:
            self._values["cinder"] = cinder
        if config_map is not None:
            self._values["config_map"] = config_map
        if csi is not None:
            self._values["csi"] = csi
        if downward_api is not None:
            self._values["downward_api"] = downward_api
        if empty_dir is not None:
            self._values["empty_dir"] = empty_dir
        if ephemeral is not None:
            self._values["ephemeral"] = ephemeral
        if fc is not None:
            self._values["fc"] = fc
        if flex_volume is not None:
            self._values["flex_volume"] = flex_volume
        if flocker is not None:
            self._values["flocker"] = flocker
        if gce_persistent_disk is not None:
            self._values["gce_persistent_disk"] = gce_persistent_disk
        if git_repo is not None:
            self._values["git_repo"] = git_repo
        if glusterfs is not None:
            self._values["glusterfs"] = glusterfs
        if host_path is not None:
            self._values["host_path"] = host_path
        if iscsi is not None:
            self._values["iscsi"] = iscsi
        if nfs is not None:
            self._values["nfs"] = nfs
        if persistent_volume_claim is not None:
            self._values["persistent_volume_claim"] = persistent_volume_claim
        if photon_persistent_disk is not None:
            self._values["photon_persistent_disk"] = photon_persistent_disk
        if portworx_volume is not None:
            self._values["portworx_volume"] = portworx_volume
        if projected is not None:
            self._values["projected"] = projected
        if quobyte is not None:
            self._values["quobyte"] = quobyte
        if rbd is not None:
            self._values["rbd"] = rbd
        if scale_io is not None:
            self._values["scale_io"] = scale_io
        if secret is not None:
            self._values["secret"] = secret
        if storageos is not None:
            self._values["storageos"] = storageos
        if vsphere_volume is not None:
            self._values["vsphere_volume"] = vsphere_volume

    @builtins.property
    def name(self) -> builtins.str:
        '''Volume's name.

        Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        :schema: io.k8s.api.core.v1.Volume#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def aws_elastic_block_store(
        self,
    ) -> typing.Optional[AwsElasticBlockStoreVolumeSource]:
        '''AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

        :schema: io.k8s.api.core.v1.Volume#awsElasticBlockStore
        '''
        result = self._values.get("aws_elastic_block_store")
        return typing.cast(typing.Optional[AwsElasticBlockStoreVolumeSource], result)

    @builtins.property
    def azure_disk(self) -> typing.Optional[AzureDiskVolumeSource]:
        '''AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.

        :schema: io.k8s.api.core.v1.Volume#azureDisk
        '''
        result = self._values.get("azure_disk")
        return typing.cast(typing.Optional[AzureDiskVolumeSource], result)

    @builtins.property
    def azure_file(self) -> typing.Optional[AzureFileVolumeSource]:
        '''AzureFile represents an Azure File Service mount on the host and bind mount to the pod.

        :schema: io.k8s.api.core.v1.Volume#azureFile
        '''
        result = self._values.get("azure_file")
        return typing.cast(typing.Optional[AzureFileVolumeSource], result)

    @builtins.property
    def cephfs(self) -> typing.Optional[CephFsVolumeSource]:
        '''CephFS represents a Ceph FS mount on the host that shares a pod's lifetime.

        :schema: io.k8s.api.core.v1.Volume#cephfs
        '''
        result = self._values.get("cephfs")
        return typing.cast(typing.Optional[CephFsVolumeSource], result)

    @builtins.property
    def cinder(self) -> typing.Optional[CinderVolumeSource]:
        '''Cinder represents a cinder volume attached and mounted on kubelets host machine.

        More info: https://examples.k8s.io/mysql-cinder-pd/README.md

        :schema: io.k8s.api.core.v1.Volume#cinder
        '''
        result = self._values.get("cinder")
        return typing.cast(typing.Optional[CinderVolumeSource], result)

    @builtins.property
    def config_map(self) -> typing.Optional[ConfigMapVolumeSource]:
        '''ConfigMap represents a configMap that should populate this volume.

        :schema: io.k8s.api.core.v1.Volume#configMap
        '''
        result = self._values.get("config_map")
        return typing.cast(typing.Optional[ConfigMapVolumeSource], result)

    @builtins.property
    def csi(self) -> typing.Optional[CsiVolumeSource]:
        '''CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).

        :schema: io.k8s.api.core.v1.Volume#csi
        '''
        result = self._values.get("csi")
        return typing.cast(typing.Optional[CsiVolumeSource], result)

    @builtins.property
    def downward_api(self) -> typing.Optional[DownwardApiVolumeSource]:
        '''DownwardAPI represents downward API about the pod that should populate this volume.

        :schema: io.k8s.api.core.v1.Volume#downwardAPI
        '''
        result = self._values.get("downward_api")
        return typing.cast(typing.Optional[DownwardApiVolumeSource], result)

    @builtins.property
    def empty_dir(self) -> typing.Optional[EmptyDirVolumeSource]:
        '''EmptyDir represents a temporary directory that shares a pod's lifetime.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

        :schema: io.k8s.api.core.v1.Volume#emptyDir
        '''
        result = self._values.get("empty_dir")
        return typing.cast(typing.Optional[EmptyDirVolumeSource], result)

    @builtins.property
    def ephemeral(self) -> typing.Optional[EphemeralVolumeSource]:
        '''Ephemeral represents a volume that is handled by a cluster storage driver.

        The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed.

        Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity
        tracking are needed,
        c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through
        a PersistentVolumeClaim (see EphemeralVolumeSource for more
        information on the connection between this volume type
        and PersistentVolumeClaim).

        Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod.

        Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information.

        A pod can use both types of ephemeral volumes and persistent volumes at the same time.

        :schema: io.k8s.api.core.v1.Volume#ephemeral
        '''
        result = self._values.get("ephemeral")
        return typing.cast(typing.Optional[EphemeralVolumeSource], result)

    @builtins.property
    def fc(self) -> typing.Optional[FcVolumeSource]:
        '''FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.

        :schema: io.k8s.api.core.v1.Volume#fc
        '''
        result = self._values.get("fc")
        return typing.cast(typing.Optional[FcVolumeSource], result)

    @builtins.property
    def flex_volume(self) -> typing.Optional[FlexVolumeSource]:
        '''FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.

        :schema: io.k8s.api.core.v1.Volume#flexVolume
        '''
        result = self._values.get("flex_volume")
        return typing.cast(typing.Optional[FlexVolumeSource], result)

    @builtins.property
    def flocker(self) -> typing.Optional[FlockerVolumeSource]:
        '''Flocker represents a Flocker volume attached to a kubelet's host machine.

        This depends on the Flocker control service being running

        :schema: io.k8s.api.core.v1.Volume#flocker
        '''
        result = self._values.get("flocker")
        return typing.cast(typing.Optional[FlockerVolumeSource], result)

    @builtins.property
    def gce_persistent_disk(self) -> typing.Optional[GcePersistentDiskVolumeSource]:
        '''GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

        :schema: io.k8s.api.core.v1.Volume#gcePersistentDisk
        '''
        result = self._values.get("gce_persistent_disk")
        return typing.cast(typing.Optional[GcePersistentDiskVolumeSource], result)

    @builtins.property
    def git_repo(self) -> typing.Optional[GitRepoVolumeSource]:
        '''GitRepo represents a git repository at a particular revision.

        DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod's container.

        :schema: io.k8s.api.core.v1.Volume#gitRepo
        '''
        result = self._values.get("git_repo")
        return typing.cast(typing.Optional[GitRepoVolumeSource], result)

    @builtins.property
    def glusterfs(self) -> typing.Optional[GlusterfsVolumeSource]:
        '''Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.

        More info: https://examples.k8s.io/volumes/glusterfs/README.md

        :schema: io.k8s.api.core.v1.Volume#glusterfs
        '''
        result = self._values.get("glusterfs")
        return typing.cast(typing.Optional[GlusterfsVolumeSource], result)

    @builtins.property
    def host_path(self) -> typing.Optional[HostPathVolumeSource]:
        '''HostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container.

        This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

        :schema: io.k8s.api.core.v1.Volume#hostPath
        '''
        result = self._values.get("host_path")
        return typing.cast(typing.Optional[HostPathVolumeSource], result)

    @builtins.property
    def iscsi(self) -> typing.Optional[IscsiVolumeSource]:
        '''ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod.

        More info: https://examples.k8s.io/volumes/iscsi/README.md

        :schema: io.k8s.api.core.v1.Volume#iscsi
        '''
        result = self._values.get("iscsi")
        return typing.cast(typing.Optional[IscsiVolumeSource], result)

    @builtins.property
    def nfs(self) -> typing.Optional[NfsVolumeSource]:
        '''NFS represents an NFS mount on the host that shares a pod's lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs.

        :schema: io.k8s.api.core.v1.Volume#nfs
        '''
        result = self._values.get("nfs")
        return typing.cast(typing.Optional[NfsVolumeSource], result)

    @builtins.property
    def persistent_volume_claim(
        self,
    ) -> typing.Optional[PersistentVolumeClaimVolumeSource]:
        '''PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace.

        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

        :schema: io.k8s.api.core.v1.Volume#persistentVolumeClaim
        '''
        result = self._values.get("persistent_volume_claim")
        return typing.cast(typing.Optional[PersistentVolumeClaimVolumeSource], result)

    @builtins.property
    def photon_persistent_disk(
        self,
    ) -> typing.Optional[PhotonPersistentDiskVolumeSource]:
        '''PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.Volume#photonPersistentDisk
        '''
        result = self._values.get("photon_persistent_disk")
        return typing.cast(typing.Optional[PhotonPersistentDiskVolumeSource], result)

    @builtins.property
    def portworx_volume(self) -> typing.Optional[PortworxVolumeSource]:
        '''PortworxVolume represents a portworx volume attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.Volume#portworxVolume
        '''
        result = self._values.get("portworx_volume")
        return typing.cast(typing.Optional[PortworxVolumeSource], result)

    @builtins.property
    def projected(self) -> typing.Optional[ProjectedVolumeSource]:
        '''Items for all in one resources secrets, configmaps, and downward API.

        :schema: io.k8s.api.core.v1.Volume#projected
        '''
        result = self._values.get("projected")
        return typing.cast(typing.Optional[ProjectedVolumeSource], result)

    @builtins.property
    def quobyte(self) -> typing.Optional[QuobyteVolumeSource]:
        '''Quobyte represents a Quobyte mount on the host that shares a pod's lifetime.

        :schema: io.k8s.api.core.v1.Volume#quobyte
        '''
        result = self._values.get("quobyte")
        return typing.cast(typing.Optional[QuobyteVolumeSource], result)

    @builtins.property
    def rbd(self) -> typing.Optional[RbdVolumeSource]:
        '''RBD represents a Rados Block Device mount on the host that shares a pod's lifetime.

        More info: https://examples.k8s.io/volumes/rbd/README.md

        :schema: io.k8s.api.core.v1.Volume#rbd
        '''
        result = self._values.get("rbd")
        return typing.cast(typing.Optional[RbdVolumeSource], result)

    @builtins.property
    def scale_io(self) -> typing.Optional[ScaleIoVolumeSource]:
        '''ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.

        :schema: io.k8s.api.core.v1.Volume#scaleIO
        '''
        result = self._values.get("scale_io")
        return typing.cast(typing.Optional[ScaleIoVolumeSource], result)

    @builtins.property
    def secret(self) -> typing.Optional[SecretVolumeSource]:
        '''Secret represents a secret that should populate this volume.

        More info: https://kubernetes.io/docs/concepts/storage/volumes#secret

        :schema: io.k8s.api.core.v1.Volume#secret
        '''
        result = self._values.get("secret")
        return typing.cast(typing.Optional[SecretVolumeSource], result)

    @builtins.property
    def storageos(self) -> typing.Optional[StorageOsVolumeSource]:
        '''StorageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.

        :schema: io.k8s.api.core.v1.Volume#storageos
        '''
        result = self._values.get("storageos")
        return typing.cast(typing.Optional[StorageOsVolumeSource], result)

    @builtins.property
    def vsphere_volume(self) -> typing.Optional["VsphereVirtualDiskVolumeSource"]:
        '''VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.

        :schema: io.k8s.api.core.v1.Volume#vsphereVolume
        '''
        result = self._values.get("vsphere_volume")
        return typing.cast(typing.Optional["VsphereVirtualDiskVolumeSource"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Volume(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeAttachmentSource",
    jsii_struct_bases=[],
    name_mapping={
        "inline_volume_spec": "inlineVolumeSpec",
        "persistent_volume_name": "persistentVolumeName",
    },
)
class VolumeAttachmentSource:
    def __init__(
        self,
        *,
        inline_volume_spec: typing.Optional[typing.Union[PersistentVolumeSpec, typing.Dict[str, typing.Any]]] = None,
        persistent_volume_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''VolumeAttachmentSource represents a volume that should be attached.

        Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.

        :param inline_volume_spec: inlineVolumeSpec contains all the information necessary to attach a persistent volume defined by a pod's inline VolumeSource. This field is populated only for the CSIMigration feature. It contains translated fields from a pod's inline VolumeSource to a PersistentVolumeSpec. This field is beta-level and is only honored by servers that enabled the CSIMigration feature.
        :param persistent_volume_name: Name of the persistent volume to attach.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSource
        '''
        if isinstance(inline_volume_spec, dict):
            inline_volume_spec = PersistentVolumeSpec(**inline_volume_spec)
        if __debug__:
            def stub(
                *,
                inline_volume_spec: typing.Optional[typing.Union[PersistentVolumeSpec, typing.Dict[str, typing.Any]]] = None,
                persistent_volume_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument inline_volume_spec", value=inline_volume_spec, expected_type=type_hints["inline_volume_spec"])
            check_type(argname="argument persistent_volume_name", value=persistent_volume_name, expected_type=type_hints["persistent_volume_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if inline_volume_spec is not None:
            self._values["inline_volume_spec"] = inline_volume_spec
        if persistent_volume_name is not None:
            self._values["persistent_volume_name"] = persistent_volume_name

    @builtins.property
    def inline_volume_spec(self) -> typing.Optional[PersistentVolumeSpec]:
        '''inlineVolumeSpec contains all the information necessary to attach a persistent volume defined by a pod's inline VolumeSource.

        This field is populated only for the CSIMigration feature. It contains translated fields from a pod's inline VolumeSource to a PersistentVolumeSpec. This field is beta-level and is only honored by servers that enabled the CSIMigration feature.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSource#inlineVolumeSpec
        '''
        result = self._values.get("inline_volume_spec")
        return typing.cast(typing.Optional[PersistentVolumeSpec], result)

    @builtins.property
    def persistent_volume_name(self) -> typing.Optional[builtins.str]:
        '''Name of the persistent volume to attach.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSource#persistentVolumeName
        '''
        result = self._values.get("persistent_volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeAttachmentSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeAttachmentSpec",
    jsii_struct_bases=[],
    name_mapping={"attacher": "attacher", "node_name": "nodeName", "source": "source"},
)
class VolumeAttachmentSpec:
    def __init__(
        self,
        *,
        attacher: builtins.str,
        node_name: builtins.str,
        source: typing.Union[VolumeAttachmentSource, typing.Dict[str, typing.Any]],
    ) -> None:
        '''VolumeAttachmentSpec is the specification of a VolumeAttachment request.

        :param attacher: Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().
        :param node_name: The node that the volume should be attached to.
        :param source: Source represents the volume that should be attached.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSpec
        '''
        if isinstance(source, dict):
            source = VolumeAttachmentSource(**source)
        if __debug__:
            def stub(
                *,
                attacher: builtins.str,
                node_name: builtins.str,
                source: typing.Union[VolumeAttachmentSource, typing.Dict[str, typing.Any]],
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument attacher", value=attacher, expected_type=type_hints["attacher"])
            check_type(argname="argument node_name", value=node_name, expected_type=type_hints["node_name"])
            check_type(argname="argument source", value=source, expected_type=type_hints["source"])
        self._values: typing.Dict[str, typing.Any] = {
            "attacher": attacher,
            "node_name": node_name,
            "source": source,
        }

    @builtins.property
    def attacher(self) -> builtins.str:
        '''Attacher indicates the name of the volume driver that MUST handle this request.

        This is the name returned by GetPluginName().

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSpec#attacher
        '''
        result = self._values.get("attacher")
        assert result is not None, "Required property 'attacher' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def node_name(self) -> builtins.str:
        '''The node that the volume should be attached to.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSpec#nodeName
        '''
        result = self._values.get("node_name")
        assert result is not None, "Required property 'node_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def source(self) -> VolumeAttachmentSource:
        '''Source represents the volume that should be attached.

        :schema: io.k8s.api.storage.v1.VolumeAttachmentSpec#source
        '''
        result = self._values.get("source")
        assert result is not None, "Required property 'source' is missing"
        return typing.cast(VolumeAttachmentSource, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeAttachmentSpec(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeDevice",
    jsii_struct_bases=[],
    name_mapping={"device_path": "devicePath", "name": "name"},
)
class VolumeDevice:
    def __init__(self, *, device_path: builtins.str, name: builtins.str) -> None:
        '''volumeDevice describes a mapping of a raw block device within a container.

        :param device_path: devicePath is the path inside of the container that the device will be mapped to.
        :param name: name must match the name of a persistentVolumeClaim in the pod.

        :schema: io.k8s.api.core.v1.VolumeDevice
        '''
        if __debug__:
            def stub(*, device_path: builtins.str, name: builtins.str) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument device_path", value=device_path, expected_type=type_hints["device_path"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        self._values: typing.Dict[str, typing.Any] = {
            "device_path": device_path,
            "name": name,
        }

    @builtins.property
    def device_path(self) -> builtins.str:
        '''devicePath is the path inside of the container that the device will be mapped to.

        :schema: io.k8s.api.core.v1.VolumeDevice#devicePath
        '''
        result = self._values.get("device_path")
        assert result is not None, "Required property 'device_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''name must match the name of a persistentVolumeClaim in the pod.

        :schema: io.k8s.api.core.v1.VolumeDevice#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeDevice(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeMount",
    jsii_struct_bases=[],
    name_mapping={
        "mount_path": "mountPath",
        "name": "name",
        "mount_propagation": "mountPropagation",
        "read_only": "readOnly",
        "sub_path": "subPath",
        "sub_path_expr": "subPathExpr",
    },
)
class VolumeMount:
    def __init__(
        self,
        *,
        mount_path: builtins.str,
        name: builtins.str,
        mount_propagation: typing.Optional[builtins.str] = None,
        read_only: typing.Optional[builtins.bool] = None,
        sub_path: typing.Optional[builtins.str] = None,
        sub_path_expr: typing.Optional[builtins.str] = None,
    ) -> None:
        '''VolumeMount describes a mounting of a Volume within a container.

        :param mount_path: Path within the container at which the volume should be mounted. Must not contain ':'.
        :param name: This must match the Name of a Volume.
        :param mount_propagation: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.
        :param read_only: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. Default: false.
        :param sub_path: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). Default: volume's root).
        :param sub_path_expr: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. Default: volume's root). SubPathExpr and SubPath are mutually exclusive.

        :schema: io.k8s.api.core.v1.VolumeMount
        '''
        if __debug__:
            def stub(
                *,
                mount_path: builtins.str,
                name: builtins.str,
                mount_propagation: typing.Optional[builtins.str] = None,
                read_only: typing.Optional[builtins.bool] = None,
                sub_path: typing.Optional[builtins.str] = None,
                sub_path_expr: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument mount_path", value=mount_path, expected_type=type_hints["mount_path"])
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
            check_type(argname="argument mount_propagation", value=mount_propagation, expected_type=type_hints["mount_propagation"])
            check_type(argname="argument read_only", value=read_only, expected_type=type_hints["read_only"])
            check_type(argname="argument sub_path", value=sub_path, expected_type=type_hints["sub_path"])
            check_type(argname="argument sub_path_expr", value=sub_path_expr, expected_type=type_hints["sub_path_expr"])
        self._values: typing.Dict[str, typing.Any] = {
            "mount_path": mount_path,
            "name": name,
        }
        if mount_propagation is not None:
            self._values["mount_propagation"] = mount_propagation
        if read_only is not None:
            self._values["read_only"] = read_only
        if sub_path is not None:
            self._values["sub_path"] = sub_path
        if sub_path_expr is not None:
            self._values["sub_path_expr"] = sub_path_expr

    @builtins.property
    def mount_path(self) -> builtins.str:
        '''Path within the container at which the volume should be mounted.

        Must not contain ':'.

        :schema: io.k8s.api.core.v1.VolumeMount#mountPath
        '''
        result = self._values.get("mount_path")
        assert result is not None, "Required property 'mount_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def name(self) -> builtins.str:
        '''This must match the Name of a Volume.

        :schema: io.k8s.api.core.v1.VolumeMount#name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def mount_propagation(self) -> typing.Optional[builtins.str]:
        '''mountPropagation determines how mounts are propagated from the host to container and the other way around.

        When not set, MountPropagationNone is used. This field is beta in 1.10.

        :schema: io.k8s.api.core.v1.VolumeMount#mountPropagation
        '''
        result = self._values.get("mount_propagation")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def read_only(self) -> typing.Optional[builtins.bool]:
        '''Mounted read-only if true, read-write otherwise (false or unspecified).

        Defaults to false.

        :default: false.

        :schema: io.k8s.api.core.v1.VolumeMount#readOnly
        '''
        result = self._values.get("read_only")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def sub_path(self) -> typing.Optional[builtins.str]:
        '''Path within the volume from which the container's volume should be mounted.

        Defaults to "" (volume's root).

        :default: volume's root).

        :schema: io.k8s.api.core.v1.VolumeMount#subPath
        '''
        result = self._values.get("sub_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def sub_path_expr(self) -> typing.Optional[builtins.str]:
        '''Expanded path within the volume from which the container's volume should be mounted.

        Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive.

        :default: volume's root). SubPathExpr and SubPath are mutually exclusive.

        :schema: io.k8s.api.core.v1.VolumeMount#subPathExpr
        '''
        result = self._values.get("sub_path_expr")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeMount(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeNodeAffinity",
    jsii_struct_bases=[],
    name_mapping={"required": "required"},
)
class VolumeNodeAffinity:
    def __init__(
        self,
        *,
        required: typing.Optional[typing.Union[NodeSelector, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''VolumeNodeAffinity defines constraints that limit what nodes this volume can be accessed from.

        :param required: Required specifies hard node constraints that must be met.

        :schema: io.k8s.api.core.v1.VolumeNodeAffinity
        '''
        if isinstance(required, dict):
            required = NodeSelector(**required)
        if __debug__:
            def stub(
                *,
                required: typing.Optional[typing.Union[NodeSelector, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument required", value=required, expected_type=type_hints["required"])
        self._values: typing.Dict[str, typing.Any] = {}
        if required is not None:
            self._values["required"] = required

    @builtins.property
    def required(self) -> typing.Optional[NodeSelector]:
        '''Required specifies hard node constraints that must be met.

        :schema: io.k8s.api.core.v1.VolumeNodeAffinity#required
        '''
        result = self._values.get("required")
        return typing.cast(typing.Optional[NodeSelector], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeNodeAffinity(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeNodeResources",
    jsii_struct_bases=[],
    name_mapping={"count": "count"},
)
class VolumeNodeResources:
    def __init__(self, *, count: typing.Optional[jsii.Number] = None) -> None:
        '''VolumeNodeResources is a set of resource limits for scheduling of volumes.

        :param count: Maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is not specified, then the supported number of volumes on this node is unbounded.

        :schema: io.k8s.api.storage.v1.VolumeNodeResources
        '''
        if __debug__:
            def stub(*, count: typing.Optional[jsii.Number] = None) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument count", value=count, expected_type=type_hints["count"])
        self._values: typing.Dict[str, typing.Any] = {}
        if count is not None:
            self._values["count"] = count

    @builtins.property
    def count(self) -> typing.Optional[jsii.Number]:
        '''Maximum number of unique volumes managed by the CSI driver that can be used on a node.

        A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is not specified, then the supported number of volumes on this node is unbounded.

        :schema: io.k8s.api.storage.v1.VolumeNodeResources#count
        '''
        result = self._values.get("count")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeNodeResources(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VolumeProjection",
    jsii_struct_bases=[],
    name_mapping={
        "config_map": "configMap",
        "downward_api": "downwardApi",
        "secret": "secret",
        "service_account_token": "serviceAccountToken",
    },
)
class VolumeProjection:
    def __init__(
        self,
        *,
        config_map: typing.Optional[typing.Union[ConfigMapProjection, typing.Dict[str, typing.Any]]] = None,
        downward_api: typing.Optional[typing.Union[DownwardApiProjection, typing.Dict[str, typing.Any]]] = None,
        secret: typing.Optional[typing.Union[SecretProjection, typing.Dict[str, typing.Any]]] = None,
        service_account_token: typing.Optional[typing.Union[ServiceAccountTokenProjection, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Projection that may be projected along with other supported volume types.

        :param config_map: information about the configMap data to project.
        :param downward_api: information about the downwardAPI data to project.
        :param secret: information about the secret data to project.
        :param service_account_token: information about the serviceAccountToken data to project.

        :schema: io.k8s.api.core.v1.VolumeProjection
        '''
        if isinstance(config_map, dict):
            config_map = ConfigMapProjection(**config_map)
        if isinstance(downward_api, dict):
            downward_api = DownwardApiProjection(**downward_api)
        if isinstance(secret, dict):
            secret = SecretProjection(**secret)
        if isinstance(service_account_token, dict):
            service_account_token = ServiceAccountTokenProjection(**service_account_token)
        if __debug__:
            def stub(
                *,
                config_map: typing.Optional[typing.Union[ConfigMapProjection, typing.Dict[str, typing.Any]]] = None,
                downward_api: typing.Optional[typing.Union[DownwardApiProjection, typing.Dict[str, typing.Any]]] = None,
                secret: typing.Optional[typing.Union[SecretProjection, typing.Dict[str, typing.Any]]] = None,
                service_account_token: typing.Optional[typing.Union[ServiceAccountTokenProjection, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument config_map", value=config_map, expected_type=type_hints["config_map"])
            check_type(argname="argument downward_api", value=downward_api, expected_type=type_hints["downward_api"])
            check_type(argname="argument secret", value=secret, expected_type=type_hints["secret"])
            check_type(argname="argument service_account_token", value=service_account_token, expected_type=type_hints["service_account_token"])
        self._values: typing.Dict[str, typing.Any] = {}
        if config_map is not None:
            self._values["config_map"] = config_map
        if downward_api is not None:
            self._values["downward_api"] = downward_api
        if secret is not None:
            self._values["secret"] = secret
        if service_account_token is not None:
            self._values["service_account_token"] = service_account_token

    @builtins.property
    def config_map(self) -> typing.Optional[ConfigMapProjection]:
        '''information about the configMap data to project.

        :schema: io.k8s.api.core.v1.VolumeProjection#configMap
        '''
        result = self._values.get("config_map")
        return typing.cast(typing.Optional[ConfigMapProjection], result)

    @builtins.property
    def downward_api(self) -> typing.Optional[DownwardApiProjection]:
        '''information about the downwardAPI data to project.

        :schema: io.k8s.api.core.v1.VolumeProjection#downwardAPI
        '''
        result = self._values.get("downward_api")
        return typing.cast(typing.Optional[DownwardApiProjection], result)

    @builtins.property
    def secret(self) -> typing.Optional[SecretProjection]:
        '''information about the secret data to project.

        :schema: io.k8s.api.core.v1.VolumeProjection#secret
        '''
        result = self._values.get("secret")
        return typing.cast(typing.Optional[SecretProjection], result)

    @builtins.property
    def service_account_token(self) -> typing.Optional[ServiceAccountTokenProjection]:
        '''information about the serviceAccountToken data to project.

        :schema: io.k8s.api.core.v1.VolumeProjection#serviceAccountToken
        '''
        result = self._values.get("service_account_token")
        return typing.cast(typing.Optional[ServiceAccountTokenProjection], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeProjection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.VsphereVirtualDiskVolumeSource",
    jsii_struct_bases=[],
    name_mapping={
        "volume_path": "volumePath",
        "fs_type": "fsType",
        "storage_policy_id": "storagePolicyId",
        "storage_policy_name": "storagePolicyName",
    },
)
class VsphereVirtualDiskVolumeSource:
    def __init__(
        self,
        *,
        volume_path: builtins.str,
        fs_type: typing.Optional[builtins.str] = None,
        storage_policy_id: typing.Optional[builtins.str] = None,
        storage_policy_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Represents a vSphere volume resource.

        :param volume_path: Path that identifies vSphere volume vmdk.
        :param fs_type: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
        :param storage_policy_id: Storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.
        :param storage_policy_name: Storage Policy Based Management (SPBM) profile name.

        :schema: io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource
        '''
        if __debug__:
            def stub(
                *,
                volume_path: builtins.str,
                fs_type: typing.Optional[builtins.str] = None,
                storage_policy_id: typing.Optional[builtins.str] = None,
                storage_policy_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument volume_path", value=volume_path, expected_type=type_hints["volume_path"])
            check_type(argname="argument fs_type", value=fs_type, expected_type=type_hints["fs_type"])
            check_type(argname="argument storage_policy_id", value=storage_policy_id, expected_type=type_hints["storage_policy_id"])
            check_type(argname="argument storage_policy_name", value=storage_policy_name, expected_type=type_hints["storage_policy_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "volume_path": volume_path,
        }
        if fs_type is not None:
            self._values["fs_type"] = fs_type
        if storage_policy_id is not None:
            self._values["storage_policy_id"] = storage_policy_id
        if storage_policy_name is not None:
            self._values["storage_policy_name"] = storage_policy_name

    @builtins.property
    def volume_path(self) -> builtins.str:
        '''Path that identifies vSphere volume vmdk.

        :schema: io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource#volumePath
        '''
        result = self._values.get("volume_path")
        assert result is not None, "Required property 'volume_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def fs_type(self) -> typing.Optional[builtins.str]:
        '''Filesystem type to mount.

        Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.

        :schema: io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource#fsType
        '''
        result = self._values.get("fs_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def storage_policy_id(self) -> typing.Optional[builtins.str]:
        '''Storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.

        :schema: io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource#storagePolicyID
        '''
        result = self._values.get("storage_policy_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def storage_policy_name(self) -> typing.Optional[builtins.str]:
        '''Storage Policy Based Management (SPBM) profile name.

        :schema: io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource#storagePolicyName
        '''
        result = self._values.get("storage_policy_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VsphereVirtualDiskVolumeSource(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.WebhookClientConfig",
    jsii_struct_bases=[],
    name_mapping={"ca_bundle": "caBundle", "service": "service", "url": "url"},
)
class WebhookClientConfig:
    def __init__(
        self,
        *,
        ca_bundle: typing.Optional[builtins.str] = None,
        service: typing.Optional[typing.Union[ServiceReference, typing.Dict[str, typing.Any]]] = None,
        url: typing.Optional[builtins.str] = None,
    ) -> None:
        '''WebhookClientConfig contains the information to make a TLS connection with the webhook.

        :param ca_bundle: ``caBundle`` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.
        :param service: ``service`` is a reference to the service for this webhook. Either ``service`` or ``url`` must be specified. If the webhook is running within the cluster, then you should use ``service``.
        :param url: ``url`` gives the location of the webhook, in standard URL form (``scheme://host:port/path``). Exactly one of ``url`` or ``service`` must be specified. The ``host`` should not refer to a service running in the cluster; use the ``service`` field instead. The host might be resolved via external DNS in some apiservers (e.g., ``kube-apiserver`` cannot resolve in-cluster DNS as that would be a layering violation). ``host`` may also be an IP address. Please note that using ``localhost`` or ``127.0.0.1`` as a ``host`` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster. The scheme must be "https"; the URL must begin with "https://". A path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier. Attempting to use a user or basic auth e.g. "user:password@" is not allowed. Fragments ("#...") and query parameters ("?...") are not allowed, either.

        :schema: io.k8s.api.admissionregistration.v1.WebhookClientConfig
        '''
        if isinstance(service, dict):
            service = ServiceReference(**service)
        if __debug__:
            def stub(
                *,
                ca_bundle: typing.Optional[builtins.str] = None,
                service: typing.Optional[typing.Union[ServiceReference, typing.Dict[str, typing.Any]]] = None,
                url: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument ca_bundle", value=ca_bundle, expected_type=type_hints["ca_bundle"])
            check_type(argname="argument service", value=service, expected_type=type_hints["service"])
            check_type(argname="argument url", value=url, expected_type=type_hints["url"])
        self._values: typing.Dict[str, typing.Any] = {}
        if ca_bundle is not None:
            self._values["ca_bundle"] = ca_bundle
        if service is not None:
            self._values["service"] = service
        if url is not None:
            self._values["url"] = url

    @builtins.property
    def ca_bundle(self) -> typing.Optional[builtins.str]:
        '''``caBundle`` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.

        If unspecified, system trust roots on the apiserver are used.

        :schema: io.k8s.api.admissionregistration.v1.WebhookClientConfig#caBundle
        '''
        result = self._values.get("ca_bundle")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service(self) -> typing.Optional[ServiceReference]:
        '''``service`` is a reference to the service for this webhook. Either ``service`` or ``url`` must be specified.

        If the webhook is running within the cluster, then you should use ``service``.

        :schema: io.k8s.api.admissionregistration.v1.WebhookClientConfig#service
        '''
        result = self._values.get("service")
        return typing.cast(typing.Optional[ServiceReference], result)

    @builtins.property
    def url(self) -> typing.Optional[builtins.str]:
        '''``url`` gives the location of the webhook, in standard URL form (``scheme://host:port/path``).

        Exactly one of ``url`` or ``service`` must be specified.

        The ``host`` should not refer to a service running in the cluster; use the ``service`` field instead. The host might be resolved via external DNS in some apiservers (e.g., ``kube-apiserver`` cannot resolve in-cluster DNS as that would be a layering violation). ``host`` may also be an IP address.

        Please note that using ``localhost`` or ``127.0.0.1`` as a ``host`` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.

        The scheme must be "https"; the URL must begin with "https://".

        A path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.

        Attempting to use a user or basic auth e.g. "user:password@" is not allowed. Fragments ("#...") and query parameters ("?...") are not allowed, either.

        :schema: io.k8s.api.admissionregistration.v1.WebhookClientConfig#url
        '''
        result = self._values.get("url")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "WebhookClientConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.WebhookConversion",
    jsii_struct_bases=[],
    name_mapping={
        "conversion_review_versions": "conversionReviewVersions",
        "client_config": "clientConfig",
    },
)
class WebhookConversion:
    def __init__(
        self,
        *,
        conversion_review_versions: typing.Sequence[builtins.str],
        client_config: typing.Optional[typing.Union[WebhookClientConfig, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''WebhookConversion describes how to call a conversion webhook.

        :param conversion_review_versions: conversionReviewVersions is an ordered list of preferred ``ConversionReview`` versions the Webhook expects. The API server will use the first version in the list which it supports. If none of the versions specified in this list are supported by API server, conversion will fail for the custom resource. 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.
        :param client_config: clientConfig is the instructions for how to call the webhook if strategy is ``Webhook``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.WebhookConversion
        '''
        if isinstance(client_config, dict):
            client_config = WebhookClientConfig(**client_config)
        if __debug__:
            def stub(
                *,
                conversion_review_versions: typing.Sequence[builtins.str],
                client_config: typing.Optional[typing.Union[WebhookClientConfig, typing.Dict[str, typing.Any]]] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument conversion_review_versions", value=conversion_review_versions, expected_type=type_hints["conversion_review_versions"])
            check_type(argname="argument client_config", value=client_config, expected_type=type_hints["client_config"])
        self._values: typing.Dict[str, typing.Any] = {
            "conversion_review_versions": conversion_review_versions,
        }
        if client_config is not None:
            self._values["client_config"] = client_config

    @builtins.property
    def conversion_review_versions(self) -> typing.List[builtins.str]:
        '''conversionReviewVersions is an ordered list of preferred ``ConversionReview`` versions the Webhook expects.

        The API server will use the first version in the list which it supports. If none of the versions specified in this list are supported by API server, conversion will fail for the custom resource. 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.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.WebhookConversion#conversionReviewVersions
        '''
        result = self._values.get("conversion_review_versions")
        assert result is not None, "Required property 'conversion_review_versions' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def client_config(self) -> typing.Optional[WebhookClientConfig]:
        '''clientConfig is the instructions for how to call the webhook if strategy is ``Webhook``.

        :schema: io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.WebhookConversion#clientConfig
        '''
        result = self._values.get("client_config")
        return typing.cast(typing.Optional[WebhookClientConfig], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "WebhookConversion(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.WeightedPodAffinityTerm",
    jsii_struct_bases=[],
    name_mapping={"pod_affinity_term": "podAffinityTerm", "weight": "weight"},
)
class WeightedPodAffinityTerm:
    def __init__(
        self,
        *,
        pod_affinity_term: typing.Union[PodAffinityTerm, typing.Dict[str, typing.Any]],
        weight: jsii.Number,
    ) -> None:
        '''The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s).

        :param pod_affinity_term: Required. A pod affinity term, associated with the corresponding weight.
        :param weight: weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

        :schema: io.k8s.api.core.v1.WeightedPodAffinityTerm
        '''
        if isinstance(pod_affinity_term, dict):
            pod_affinity_term = PodAffinityTerm(**pod_affinity_term)
        if __debug__:
            def stub(
                *,
                pod_affinity_term: typing.Union[PodAffinityTerm, typing.Dict[str, typing.Any]],
                weight: jsii.Number,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument pod_affinity_term", value=pod_affinity_term, expected_type=type_hints["pod_affinity_term"])
            check_type(argname="argument weight", value=weight, expected_type=type_hints["weight"])
        self._values: typing.Dict[str, typing.Any] = {
            "pod_affinity_term": pod_affinity_term,
            "weight": weight,
        }

    @builtins.property
    def pod_affinity_term(self) -> PodAffinityTerm:
        '''Required.

        A pod affinity term, associated with the corresponding weight.

        :schema: io.k8s.api.core.v1.WeightedPodAffinityTerm#podAffinityTerm
        '''
        result = self._values.get("pod_affinity_term")
        assert result is not None, "Required property 'pod_affinity_term' is missing"
        return typing.cast(PodAffinityTerm, result)

    @builtins.property
    def weight(self) -> jsii.Number:
        '''weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

        :schema: io.k8s.api.core.v1.WeightedPodAffinityTerm#weight
        '''
        result = self._values.get("weight")
        assert result is not None, "Required property 'weight' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "WeightedPodAffinityTerm(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="cdk8s-plus-23.k8s.WindowsSecurityContextOptions",
    jsii_struct_bases=[],
    name_mapping={
        "gmsa_credential_spec": "gmsaCredentialSpec",
        "gmsa_credential_spec_name": "gmsaCredentialSpecName",
        "host_process": "hostProcess",
        "run_as_user_name": "runAsUserName",
    },
)
class WindowsSecurityContextOptions:
    def __init__(
        self,
        *,
        gmsa_credential_spec: typing.Optional[builtins.str] = None,
        gmsa_credential_spec_name: typing.Optional[builtins.str] = None,
        host_process: typing.Optional[builtins.bool] = None,
        run_as_user_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''WindowsSecurityContextOptions contain Windows-specific options and credentials.

        :param gmsa_credential_spec: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field.
        :param gmsa_credential_spec_name: GMSACredentialSpecName is the name of the GMSA credential spec to use.
        :param host_process: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true.
        :param run_as_user_name: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Default: the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.

        :schema: io.k8s.api.core.v1.WindowsSecurityContextOptions
        '''
        if __debug__:
            def stub(
                *,
                gmsa_credential_spec: typing.Optional[builtins.str] = None,
                gmsa_credential_spec_name: typing.Optional[builtins.str] = None,
                host_process: typing.Optional[builtins.bool] = None,
                run_as_user_name: typing.Optional[builtins.str] = None,
            ) -> None:
                ...
            type_hints = typing.get_type_hints(stub)
            check_type(argname="argument gmsa_credential_spec", value=gmsa_credential_spec, expected_type=type_hints["gmsa_credential_spec"])
            check_type(argname="argument gmsa_credential_spec_name", value=gmsa_credential_spec_name, expected_type=type_hints["gmsa_credential_spec_name"])
            check_type(argname="argument host_process", value=host_process, expected_type=type_hints["host_process"])
            check_type(argname="argument run_as_user_name", value=run_as_user_name, expected_type=type_hints["run_as_user_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if gmsa_credential_spec is not None:
            self._values["gmsa_credential_spec"] = gmsa_credential_spec
        if gmsa_credential_spec_name is not None:
            self._values["gmsa_credential_spec_name"] = gmsa_credential_spec_name
        if host_process is not None:
            self._values["host_process"] = host_process
        if run_as_user_name is not None:
            self._values["run_as_user_name"] = run_as_user_name

    @builtins.property
    def gmsa_credential_spec(self) -> typing.Optional[builtins.str]:
        '''GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field.

        :schema: io.k8s.api.core.v1.WindowsSecurityContextOptions#gmsaCredentialSpec
        '''
        result = self._values.get("gmsa_credential_spec")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def gmsa_credential_spec_name(self) -> typing.Optional[builtins.str]:
        '''GMSACredentialSpecName is the name of the GMSA credential spec to use.

        :schema: io.k8s.api.core.v1.WindowsSecurityContextOptions#gmsaCredentialSpecName
        '''
        result = self._values.get("gmsa_credential_spec_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def host_process(self) -> typing.Optional[builtins.bool]:
        '''HostProcess determines if a container should be run as a 'Host Process' container.

        This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).  In addition, if HostProcess is true then HostNetwork must also be set to true.

        :schema: io.k8s.api.core.v1.WindowsSecurityContextOptions#hostProcess
        '''
        result = self._values.get("host_process")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def run_as_user_name(self) -> typing.Optional[builtins.str]:
        '''The UserName in Windows to run the entrypoint of the container process.

        Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.

        :default: the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.

        :schema: io.k8s.api.core.v1.WindowsSecurityContextOptions#runAsUserName
        '''
        result = self._values.get("run_as_user_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "WindowsSecurityContextOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


__all__ = [
    "Affinity",
    "AggregationRule",
    "AllowedCsiDriverV1Beta1",
    "AllowedFlexVolumeV1Beta1",
    "AllowedHostPathV1Beta1",
    "ApiServiceSpec",
    "AwsElasticBlockStoreVolumeSource",
    "AzureDiskVolumeSource",
    "AzureFilePersistentVolumeSource",
    "AzureFileVolumeSource",
    "BoundObjectReference",
    "Capabilities",
    "CephFsPersistentVolumeSource",
    "CephFsVolumeSource",
    "CertificateSigningRequestSpec",
    "CinderPersistentVolumeSource",
    "CinderVolumeSource",
    "ClientIpConfig",
    "ComponentCondition",
    "ConfigMapEnvSource",
    "ConfigMapKeySelector",
    "ConfigMapNodeConfigSource",
    "ConfigMapProjection",
    "ConfigMapVolumeSource",
    "Container",
    "ContainerPort",
    "ContainerResourceMetricSourceV2",
    "ContainerResourceMetricSourceV2Beta1",
    "ContainerResourceMetricSourceV2Beta2",
    "CronJobSpec",
    "CronJobSpecV1Beta1",
    "CrossVersionObjectReference",
    "CrossVersionObjectReferenceV2",
    "CrossVersionObjectReferenceV2Beta1",
    "CrossVersionObjectReferenceV2Beta2",
    "CsiDriverSpec",
    "CsiNodeDriver",
    "CsiNodeSpec",
    "CsiPersistentVolumeSource",
    "CsiVolumeSource",
    "CustomResourceColumnDefinition",
    "CustomResourceConversion",
    "CustomResourceDefinitionNames",
    "CustomResourceDefinitionSpec",
    "CustomResourceDefinitionVersion",
    "CustomResourceSubresourceScale",
    "CustomResourceSubresources",
    "CustomResourceValidation",
    "DaemonSetSpec",
    "DaemonSetUpdateStrategy",
    "DeleteOptions",
    "DeploymentSpec",
    "DeploymentStrategy",
    "DownwardApiProjection",
    "DownwardApiVolumeFile",
    "DownwardApiVolumeSource",
    "EmptyDirVolumeSource",
    "Endpoint",
    "EndpointAddress",
    "EndpointConditions",
    "EndpointConditionsV1Beta1",
    "EndpointHints",
    "EndpointHintsV1Beta1",
    "EndpointPort",
    "EndpointPortV1Beta1",
    "EndpointSubset",
    "EndpointV1Beta1",
    "EnvFromSource",
    "EnvVar",
    "EnvVarSource",
    "EphemeralContainer",
    "EphemeralVolumeSource",
    "EventSeries",
    "EventSeriesV1Beta1",
    "EventSource",
    "ExecAction",
    "ExternalDocumentation",
    "ExternalMetricSourceV2",
    "ExternalMetricSourceV2Beta1",
    "ExternalMetricSourceV2Beta2",
    "FcVolumeSource",
    "FlexPersistentVolumeSource",
    "FlexVolumeSource",
    "FlockerVolumeSource",
    "FlowDistinguisherMethodV1Beta1",
    "FlowDistinguisherMethodV1Beta2",
    "FlowSchemaSpecV1Beta1",
    "FlowSchemaSpecV1Beta2",
    "ForZone",
    "ForZoneV1Beta1",
    "FsGroupStrategyOptionsV1Beta1",
    "GcePersistentDiskVolumeSource",
    "GitRepoVolumeSource",
    "GlusterfsPersistentVolumeSource",
    "GlusterfsVolumeSource",
    "GroupSubjectV1Beta1",
    "GroupSubjectV1Beta2",
    "GrpcAction",
    "HorizontalPodAutoscalerBehaviorV2",
    "HorizontalPodAutoscalerBehaviorV2Beta2",
    "HorizontalPodAutoscalerSpec",
    "HorizontalPodAutoscalerSpecV2",
    "HorizontalPodAutoscalerSpecV2Beta1",
    "HorizontalPodAutoscalerSpecV2Beta2",
    "HostAlias",
    "HostPathVolumeSource",
    "HostPortRangeV1Beta1",
    "HpaScalingPolicyV2",
    "HpaScalingPolicyV2Beta2",
    "HpaScalingRulesV2",
    "HpaScalingRulesV2Beta2",
    "HttpGetAction",
    "HttpHeader",
    "HttpIngressPath",
    "HttpIngressRuleValue",
    "IdRangeV1Beta1",
    "IngressBackend",
    "IngressClassParametersReference",
    "IngressClassSpec",
    "IngressRule",
    "IngressServiceBackend",
    "IngressSpec",
    "IngressTls",
    "IntOrString",
    "IoK8SApiAppsV1DaemonSetUpdateStrategyType",
    "IoK8SApiAppsV1DeploymentStrategyType",
    "IoK8SApiAppsV1StatefulSetSpecPodManagementPolicy",
    "IoK8SApiAppsV1StatefulSetUpdateStrategyType",
    "IoK8SApiBatchV1CronJobSpecConcurrencyPolicy",
    "IoK8SApiCoreV1ContainerImagePullPolicy",
    "IoK8SApiCoreV1ContainerPortProtocol",
    "IoK8SApiCoreV1ContainerTerminationMessagePolicy",
    "IoK8SApiCoreV1EndpointPortProtocol",
    "IoK8SApiCoreV1EphemeralContainerImagePullPolicy",
    "IoK8SApiCoreV1EphemeralContainerTerminationMessagePolicy",
    "IoK8SApiCoreV1HttpGetActionScheme",
    "IoK8SApiCoreV1LimitRangeItemType",
    "IoK8SApiCoreV1NodeSelectorRequirementOperator",
    "IoK8SApiCoreV1PersistentVolumeSpecPersistentVolumeReclaimPolicy",
    "IoK8SApiCoreV1PodReadinessGateConditionType",
    "IoK8SApiCoreV1PodSpecDnsPolicy",
    "IoK8SApiCoreV1PodSpecRestartPolicy",
    "IoK8SApiCoreV1ScopedResourceSelectorRequirementOperator",
    "IoK8SApiCoreV1ScopedResourceSelectorRequirementScopeName",
    "IoK8SApiCoreV1SeccompProfileType",
    "IoK8SApiCoreV1ServicePortProtocol",
    "IoK8SApiCoreV1ServiceSpecExternalTrafficPolicy",
    "IoK8SApiCoreV1ServiceSpecSessionAffinity",
    "IoK8SApiCoreV1ServiceSpecType",
    "IoK8SApiCoreV1TaintEffect",
    "IoK8SApiCoreV1TolerationEffect",
    "IoK8SApiCoreV1TolerationOperator",
    "IoK8SApiCoreV1TopologySpreadConstraintWhenUnsatisfiable",
    "IoK8SApiDiscoveryV1EndpointSliceAddressType",
    "IoK8SApimachineryPkgApisMetaV1DeleteOptionsKind",
    "IpBlock",
    "IscsiPersistentVolumeSource",
    "IscsiVolumeSource",
    "JobSpec",
    "JobTemplateSpec",
    "JobTemplateSpecV1Beta1",
    "JsonSchemaProps",
    "KeyToPath",
    "KubeApiService",
    "KubeApiServiceList",
    "KubeApiServiceListProps",
    "KubeApiServiceProps",
    "KubeBinding",
    "KubeBindingProps",
    "KubeCertificateSigningRequest",
    "KubeCertificateSigningRequestList",
    "KubeCertificateSigningRequestListProps",
    "KubeCertificateSigningRequestProps",
    "KubeClusterRole",
    "KubeClusterRoleBinding",
    "KubeClusterRoleBindingList",
    "KubeClusterRoleBindingListProps",
    "KubeClusterRoleBindingProps",
    "KubeClusterRoleList",
    "KubeClusterRoleListProps",
    "KubeClusterRoleProps",
    "KubeComponentStatus",
    "KubeComponentStatusList",
    "KubeComponentStatusListProps",
    "KubeComponentStatusProps",
    "KubeConfigMap",
    "KubeConfigMapList",
    "KubeConfigMapListProps",
    "KubeConfigMapProps",
    "KubeControllerRevision",
    "KubeControllerRevisionList",
    "KubeControllerRevisionListProps",
    "KubeControllerRevisionProps",
    "KubeCronJob",
    "KubeCronJobList",
    "KubeCronJobListProps",
    "KubeCronJobListV1Beta1",
    "KubeCronJobListV1Beta1Props",
    "KubeCronJobProps",
    "KubeCronJobV1Beta1",
    "KubeCronJobV1Beta1Props",
    "KubeCsiDriver",
    "KubeCsiDriverList",
    "KubeCsiDriverListProps",
    "KubeCsiDriverProps",
    "KubeCsiNode",
    "KubeCsiNodeList",
    "KubeCsiNodeListProps",
    "KubeCsiNodeProps",
    "KubeCsiStorageCapacityListV1Alpha1",
    "KubeCsiStorageCapacityListV1Alpha1Props",
    "KubeCsiStorageCapacityListV1Beta1",
    "KubeCsiStorageCapacityListV1Beta1Props",
    "KubeCsiStorageCapacityV1Alpha1",
    "KubeCsiStorageCapacityV1Alpha1Props",
    "KubeCsiStorageCapacityV1Beta1",
    "KubeCsiStorageCapacityV1Beta1Props",
    "KubeCustomResourceDefinition",
    "KubeCustomResourceDefinitionList",
    "KubeCustomResourceDefinitionListProps",
    "KubeCustomResourceDefinitionProps",
    "KubeDaemonSet",
    "KubeDaemonSetList",
    "KubeDaemonSetListProps",
    "KubeDaemonSetProps",
    "KubeDeployment",
    "KubeDeploymentList",
    "KubeDeploymentListProps",
    "KubeDeploymentProps",
    "KubeEndpointSlice",
    "KubeEndpointSliceList",
    "KubeEndpointSliceListProps",
    "KubeEndpointSliceListV1Beta1",
    "KubeEndpointSliceListV1Beta1Props",
    "KubeEndpointSliceProps",
    "KubeEndpointSliceV1Beta1",
    "KubeEndpointSliceV1Beta1Props",
    "KubeEndpoints",
    "KubeEndpointsList",
    "KubeEndpointsListProps",
    "KubeEndpointsProps",
    "KubeEvent",
    "KubeEventList",
    "KubeEventListProps",
    "KubeEventListV1Beta1",
    "KubeEventListV1Beta1Props",
    "KubeEventProps",
    "KubeEventV1Beta1",
    "KubeEventV1Beta1Props",
    "KubeEviction",
    "KubeEvictionProps",
    "KubeFlowSchemaListV1Beta1",
    "KubeFlowSchemaListV1Beta1Props",
    "KubeFlowSchemaListV1Beta2",
    "KubeFlowSchemaListV1Beta2Props",
    "KubeFlowSchemaV1Beta1",
    "KubeFlowSchemaV1Beta1Props",
    "KubeFlowSchemaV1Beta2",
    "KubeFlowSchemaV1Beta2Props",
    "KubeHorizontalPodAutoscaler",
    "KubeHorizontalPodAutoscalerList",
    "KubeHorizontalPodAutoscalerListProps",
    "KubeHorizontalPodAutoscalerListV2",
    "KubeHorizontalPodAutoscalerListV2Beta1",
    "KubeHorizontalPodAutoscalerListV2Beta1Props",
    "KubeHorizontalPodAutoscalerListV2Beta2",
    "KubeHorizontalPodAutoscalerListV2Beta2Props",
    "KubeHorizontalPodAutoscalerListV2Props",
    "KubeHorizontalPodAutoscalerProps",
    "KubeHorizontalPodAutoscalerV2",
    "KubeHorizontalPodAutoscalerV2Beta1",
    "KubeHorizontalPodAutoscalerV2Beta1Props",
    "KubeHorizontalPodAutoscalerV2Beta2",
    "KubeHorizontalPodAutoscalerV2Beta2Props",
    "KubeHorizontalPodAutoscalerV2Props",
    "KubeIngress",
    "KubeIngressClass",
    "KubeIngressClassList",
    "KubeIngressClassListProps",
    "KubeIngressClassProps",
    "KubeIngressList",
    "KubeIngressListProps",
    "KubeIngressProps",
    "KubeJob",
    "KubeJobList",
    "KubeJobListProps",
    "KubeJobProps",
    "KubeLease",
    "KubeLeaseList",
    "KubeLeaseListProps",
    "KubeLeaseProps",
    "KubeLimitRange",
    "KubeLimitRangeList",
    "KubeLimitRangeListProps",
    "KubeLimitRangeProps",
    "KubeLocalSubjectAccessReview",
    "KubeLocalSubjectAccessReviewProps",
    "KubeMutatingWebhookConfiguration",
    "KubeMutatingWebhookConfigurationList",
    "KubeMutatingWebhookConfigurationListProps",
    "KubeMutatingWebhookConfigurationProps",
    "KubeNamespace",
    "KubeNamespaceList",
    "KubeNamespaceListProps",
    "KubeNamespaceProps",
    "KubeNetworkPolicy",
    "KubeNetworkPolicyList",
    "KubeNetworkPolicyListProps",
    "KubeNetworkPolicyProps",
    "KubeNode",
    "KubeNodeList",
    "KubeNodeListProps",
    "KubeNodeProps",
    "KubePersistentVolume",
    "KubePersistentVolumeClaim",
    "KubePersistentVolumeClaimList",
    "KubePersistentVolumeClaimListProps",
    "KubePersistentVolumeClaimProps",
    "KubePersistentVolumeList",
    "KubePersistentVolumeListProps",
    "KubePersistentVolumeProps",
    "KubePod",
    "KubePodDisruptionBudget",
    "KubePodDisruptionBudgetList",
    "KubePodDisruptionBudgetListProps",
    "KubePodDisruptionBudgetListV1Beta1",
    "KubePodDisruptionBudgetListV1Beta1Props",
    "KubePodDisruptionBudgetProps",
    "KubePodDisruptionBudgetV1Beta1",
    "KubePodDisruptionBudgetV1Beta1Props",
    "KubePodList",
    "KubePodListProps",
    "KubePodProps",
    "KubePodSecurityPolicyListV1Beta1",
    "KubePodSecurityPolicyListV1Beta1Props",
    "KubePodSecurityPolicyV1Beta1",
    "KubePodSecurityPolicyV1Beta1Props",
    "KubePodTemplate",
    "KubePodTemplateList",
    "KubePodTemplateListProps",
    "KubePodTemplateProps",
    "KubePriorityClass",
    "KubePriorityClassList",
    "KubePriorityClassListProps",
    "KubePriorityClassProps",
    "KubePriorityLevelConfigurationListV1Beta1",
    "KubePriorityLevelConfigurationListV1Beta1Props",
    "KubePriorityLevelConfigurationListV1Beta2",
    "KubePriorityLevelConfigurationListV1Beta2Props",
    "KubePriorityLevelConfigurationV1Beta1",
    "KubePriorityLevelConfigurationV1Beta1Props",
    "KubePriorityLevelConfigurationV1Beta2",
    "KubePriorityLevelConfigurationV1Beta2Props",
    "KubeReplicaSet",
    "KubeReplicaSetList",
    "KubeReplicaSetListProps",
    "KubeReplicaSetProps",
    "KubeReplicationController",
    "KubeReplicationControllerList",
    "KubeReplicationControllerListProps",
    "KubeReplicationControllerProps",
    "KubeResourceQuota",
    "KubeResourceQuotaList",
    "KubeResourceQuotaListProps",
    "KubeResourceQuotaProps",
    "KubeRole",
    "KubeRoleBinding",
    "KubeRoleBindingList",
    "KubeRoleBindingListProps",
    "KubeRoleBindingProps",
    "KubeRoleList",
    "KubeRoleListProps",
    "KubeRoleProps",
    "KubeRuntimeClass",
    "KubeRuntimeClassList",
    "KubeRuntimeClassListProps",
    "KubeRuntimeClassListV1Alpha1",
    "KubeRuntimeClassListV1Alpha1Props",
    "KubeRuntimeClassListV1Beta1",
    "KubeRuntimeClassListV1Beta1Props",
    "KubeRuntimeClassProps",
    "KubeRuntimeClassV1Alpha1",
    "KubeRuntimeClassV1Alpha1Props",
    "KubeRuntimeClassV1Beta1",
    "KubeRuntimeClassV1Beta1Props",
    "KubeScale",
    "KubeScaleProps",
    "KubeSecret",
    "KubeSecretList",
    "KubeSecretListProps",
    "KubeSecretProps",
    "KubeSelfSubjectAccessReview",
    "KubeSelfSubjectAccessReviewProps",
    "KubeSelfSubjectRulesReview",
    "KubeSelfSubjectRulesReviewProps",
    "KubeService",
    "KubeServiceAccount",
    "KubeServiceAccountList",
    "KubeServiceAccountListProps",
    "KubeServiceAccountProps",
    "KubeServiceList",
    "KubeServiceListProps",
    "KubeServiceProps",
    "KubeStatefulSet",
    "KubeStatefulSetList",
    "KubeStatefulSetListProps",
    "KubeStatefulSetProps",
    "KubeStatus",
    "KubeStatusProps",
    "KubeStorageClass",
    "KubeStorageClassList",
    "KubeStorageClassListProps",
    "KubeStorageClassProps",
    "KubeStorageVersionListV1Alpha1",
    "KubeStorageVersionListV1Alpha1Props",
    "KubeStorageVersionV1Alpha1",
    "KubeStorageVersionV1Alpha1Props",
    "KubeSubjectAccessReview",
    "KubeSubjectAccessReviewProps",
    "KubeTokenRequest",
    "KubeTokenRequestProps",
    "KubeTokenReview",
    "KubeTokenReviewProps",
    "KubeValidatingWebhookConfiguration",
    "KubeValidatingWebhookConfigurationList",
    "KubeValidatingWebhookConfigurationListProps",
    "KubeValidatingWebhookConfigurationProps",
    "KubeVolumeAttachment",
    "KubeVolumeAttachmentList",
    "KubeVolumeAttachmentListProps",
    "KubeVolumeAttachmentProps",
    "LabelSelector",
    "LabelSelectorRequirement",
    "LeaseSpec",
    "Lifecycle",
    "LifecycleHandler",
    "LimitRangeItem",
    "LimitRangeSpec",
    "LimitResponseV1Beta1",
    "LimitResponseV1Beta2",
    "LimitedPriorityLevelConfigurationV1Beta1",
    "LimitedPriorityLevelConfigurationV1Beta2",
    "ListMeta",
    "LocalObjectReference",
    "LocalVolumeSource",
    "ManagedFieldsEntry",
    "MetricIdentifierV2",
    "MetricIdentifierV2Beta2",
    "MetricSpecV2",
    "MetricSpecV2Beta1",
    "MetricSpecV2Beta2",
    "MetricTargetV2",
    "MetricTargetV2Beta2",
    "MutatingWebhook",
    "NamespaceSpec",
    "NetworkPolicyEgressRule",
    "NetworkPolicyIngressRule",
    "NetworkPolicyPeer",
    "NetworkPolicyPort",
    "NetworkPolicySpec",
    "NfsVolumeSource",
    "NodeAffinity",
    "NodeConfigSource",
    "NodeSelector",
    "NodeSelectorRequirement",
    "NodeSelectorTerm",
    "NodeSpec",
    "NonResourceAttributes",
    "NonResourcePolicyRuleV1Beta1",
    "NonResourcePolicyRuleV1Beta2",
    "ObjectFieldSelector",
    "ObjectMeta",
    "ObjectMetricSourceV2",
    "ObjectMetricSourceV2Beta1",
    "ObjectMetricSourceV2Beta2",
    "ObjectReference",
    "Overhead",
    "OverheadV1Alpha1",
    "OverheadV1Beta1",
    "OwnerReference",
    "PersistentVolumeClaimSpec",
    "PersistentVolumeClaimTemplate",
    "PersistentVolumeClaimVolumeSource",
    "PersistentVolumeSpec",
    "PhotonPersistentDiskVolumeSource",
    "PodAffinity",
    "PodAffinityTerm",
    "PodAntiAffinity",
    "PodDisruptionBudgetSpec",
    "PodDisruptionBudgetSpecV1Beta1",
    "PodDnsConfig",
    "PodDnsConfigOption",
    "PodOs",
    "PodReadinessGate",
    "PodSecurityContext",
    "PodSecurityPolicySpecV1Beta1",
    "PodSpec",
    "PodTemplateSpec",
    "PodsMetricSourceV2",
    "PodsMetricSourceV2Beta1",
    "PodsMetricSourceV2Beta2",
    "PolicyRule",
    "PolicyRulesWithSubjectsV1Beta1",
    "PolicyRulesWithSubjectsV1Beta2",
    "PortworxVolumeSource",
    "Preconditions",
    "PreferredSchedulingTerm",
    "PriorityLevelConfigurationReferenceV1Beta1",
    "PriorityLevelConfigurationReferenceV1Beta2",
    "PriorityLevelConfigurationSpecV1Beta1",
    "PriorityLevelConfigurationSpecV1Beta2",
    "Probe",
    "ProjectedVolumeSource",
    "Quantity",
    "QueuingConfigurationV1Beta1",
    "QueuingConfigurationV1Beta2",
    "QuobyteVolumeSource",
    "RbdPersistentVolumeSource",
    "RbdVolumeSource",
    "ReplicaSetSpec",
    "ReplicationControllerSpec",
    "ResourceAttributes",
    "ResourceFieldSelector",
    "ResourceMetricSourceV2",
    "ResourceMetricSourceV2Beta1",
    "ResourceMetricSourceV2Beta2",
    "ResourcePolicyRuleV1Beta1",
    "ResourcePolicyRuleV1Beta2",
    "ResourceQuotaSpec",
    "ResourceRequirements",
    "RoleRef",
    "RollingUpdateDaemonSet",
    "RollingUpdateDeployment",
    "RollingUpdateStatefulSetStrategy",
    "RuleWithOperations",
    "RunAsGroupStrategyOptionsV1Beta1",
    "RunAsUserStrategyOptionsV1Beta1",
    "RuntimeClassSpecV1Alpha1",
    "RuntimeClassStrategyOptionsV1Beta1",
    "ScaleIoPersistentVolumeSource",
    "ScaleIoVolumeSource",
    "ScaleSpec",
    "Scheduling",
    "SchedulingV1Alpha1",
    "SchedulingV1Beta1",
    "ScopeSelector",
    "ScopedResourceSelectorRequirement",
    "SeLinuxOptions",
    "SeLinuxStrategyOptionsV1Beta1",
    "SeccompProfile",
    "SecretEnvSource",
    "SecretKeySelector",
    "SecretProjection",
    "SecretReference",
    "SecretVolumeSource",
    "SecurityContext",
    "SelfSubjectAccessReviewSpec",
    "SelfSubjectRulesReviewSpec",
    "ServiceAccountSubjectV1Beta1",
    "ServiceAccountSubjectV1Beta2",
    "ServiceAccountTokenProjection",
    "ServiceBackendPort",
    "ServicePort",
    "ServiceReference",
    "ServiceSpec",
    "SessionAffinityConfig",
    "StatefulSetPersistentVolumeClaimRetentionPolicy",
    "StatefulSetSpec",
    "StatefulSetUpdateStrategy",
    "StatusCause",
    "StatusDetails",
    "StorageOsPersistentVolumeSource",
    "StorageOsVolumeSource",
    "Subject",
    "SubjectAccessReviewSpec",
    "SubjectV1Beta1",
    "SubjectV1Beta2",
    "SupplementalGroupsStrategyOptionsV1Beta1",
    "Sysctl",
    "Taint",
    "TcpSocketAction",
    "TokenRequest",
    "TokenRequestSpec",
    "TokenReviewSpec",
    "Toleration",
    "TopologySelectorLabelRequirement",
    "TopologySelectorTerm",
    "TopologySpreadConstraint",
    "TypedLocalObjectReference",
    "UserSubjectV1Beta1",
    "UserSubjectV1Beta2",
    "ValidatingWebhook",
    "ValidationRule",
    "Volume",
    "VolumeAttachmentSource",
    "VolumeAttachmentSpec",
    "VolumeDevice",
    "VolumeMount",
    "VolumeNodeAffinity",
    "VolumeNodeResources",
    "VolumeProjection",
    "VsphereVirtualDiskVolumeSource",
    "WebhookClientConfig",
    "WebhookConversion",
    "WeightedPodAffinityTerm",
    "WindowsSecurityContextOptions",
]

publication.publish()
