// Code generated by cue get go. DO NOT EDIT.

//cue:generate cue get go k8s.io/api/core/v1

package v1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	"k8s.io/apimachinery/pkg/util/intstr"
	"k8s.io/apimachinery/pkg/types"
)

// NamespaceDefault means the object is in the default namespace which is applied when not specified by clients
#NamespaceDefault: "default"

// NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces
#NamespaceAll: ""

// NamespaceNodeLease is the namespace where we place node lease objects (used for node heartbeats)
#NamespaceNodeLease: "kube-node-lease"

// Volume represents a named volume in a pod that may be accessed by any container in the pod.
#Volume: {
	// 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
	name: string @go(Name) @protobuf(1,bytes,opt)

	#VolumeSource
}

// Represents the source of a volume to mount.
// Only one of its members may be specified.
#VolumeSource: {
	// 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
	// ---
	// TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not
	// mount host directories as read/write.
	// +optional
	hostPath?: null | #HostPathVolumeSource @go(HostPath,*HostPathVolumeSource) @protobuf(1,bytes,opt)

	// EmptyDir represents a temporary directory that shares a pod's lifetime.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
	// +optional
	emptyDir?: null | #EmptyDirVolumeSource @go(EmptyDir,*EmptyDirVolumeSource) @protobuf(2,bytes,opt)

	// 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
	// +optional
	gcePersistentDisk?: null | #GCEPersistentDiskVolumeSource @go(GCEPersistentDisk,*GCEPersistentDiskVolumeSource) @protobuf(3,bytes,opt)

	// 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
	// +optional
	awsElasticBlockStore?: null | #AWSElasticBlockStoreVolumeSource @go(AWSElasticBlockStore,*AWSElasticBlockStoreVolumeSource) @protobuf(4,bytes,opt)

	// 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.
	// +optional
	gitRepo?: null | #GitRepoVolumeSource @go(GitRepo,*GitRepoVolumeSource) @protobuf(5,bytes,opt)

	// Secret represents a secret that should populate this volume.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#secret
	// +optional
	secret?: null | #SecretVolumeSource @go(Secret,*SecretVolumeSource) @protobuf(6,bytes,opt)

	// NFS represents an NFS mount on the host that shares a pod's lifetime
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
	// +optional
	nfs?: null | #NFSVolumeSource @go(NFS,*NFSVolumeSource) @protobuf(7,bytes,opt)

	// 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
	// +optional
	iscsi?: null | #ISCSIVolumeSource @go(ISCSI,*ISCSIVolumeSource) @protobuf(8,bytes,opt)

	// Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
	// More info: https://examples.k8s.io/volumes/glusterfs/README.md
	// +optional
	glusterfs?: null | #GlusterfsVolumeSource @go(Glusterfs,*GlusterfsVolumeSource) @protobuf(9,bytes,opt)

	// PersistentVolumeClaimVolumeSource represents a reference to a
	// PersistentVolumeClaim in the same namespace.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
	// +optional
	persistentVolumeClaim?: null | #PersistentVolumeClaimVolumeSource @go(PersistentVolumeClaim,*PersistentVolumeClaimVolumeSource) @protobuf(10,bytes,opt)

	// 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
	// +optional
	rbd?: null | #RBDVolumeSource @go(RBD,*RBDVolumeSource) @protobuf(11,bytes,opt)

	// FlexVolume represents a generic volume resource that is
	// provisioned/attached using an exec based plugin.
	// +optional
	flexVolume?: null | #FlexVolumeSource @go(FlexVolume,*FlexVolumeSource) @protobuf(12,bytes,opt)

	// Cinder represents a cinder volume attached and mounted on kubelets host machine.
	// More info: https://examples.k8s.io/mysql-cinder-pd/README.md
	// +optional
	cinder?: null | #CinderVolumeSource @go(Cinder,*CinderVolumeSource) @protobuf(13,bytes,opt)

	// CephFS represents a Ceph FS mount on the host that shares a pod's lifetime
	// +optional
	cephfs?: null | #CephFSVolumeSource @go(CephFS,*CephFSVolumeSource) @protobuf(14,bytes,opt)

	// Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running
	// +optional
	flocker?: null | #FlockerVolumeSource @go(Flocker,*FlockerVolumeSource) @protobuf(15,bytes,opt)

	// DownwardAPI represents downward API about the pod that should populate this volume
	// +optional
	downwardAPI?: null | #DownwardAPIVolumeSource @go(DownwardAPI,*DownwardAPIVolumeSource) @protobuf(16,bytes,opt)

	// FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.
	// +optional
	fc?: null | #FCVolumeSource @go(FC,*FCVolumeSource) @protobuf(17,bytes,opt)

	// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
	// +optional
	azureFile?: null | #AzureFileVolumeSource @go(AzureFile,*AzureFileVolumeSource) @protobuf(18,bytes,opt)

	// ConfigMap represents a configMap that should populate this volume
	// +optional
	configMap?: null | #ConfigMapVolumeSource @go(ConfigMap,*ConfigMapVolumeSource) @protobuf(19,bytes,opt)

	// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
	// +optional
	vsphereVolume?: null | #VsphereVirtualDiskVolumeSource @go(VsphereVolume,*VsphereVirtualDiskVolumeSource) @protobuf(20,bytes,opt)

	// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
	// +optional
	quobyte?: null | #QuobyteVolumeSource @go(Quobyte,*QuobyteVolumeSource) @protobuf(21,bytes,opt)

	// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
	// +optional
	azureDisk?: null | #AzureDiskVolumeSource @go(AzureDisk,*AzureDiskVolumeSource) @protobuf(22,bytes,opt)

	// PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine
	photonPersistentDisk?: null | #PhotonPersistentDiskVolumeSource @go(PhotonPersistentDisk,*PhotonPersistentDiskVolumeSource) @protobuf(23,bytes,opt)

	// Items for all in one resources secrets, configmaps, and downward API
	projected?: null | #ProjectedVolumeSource @go(Projected,*ProjectedVolumeSource) @protobuf(26,bytes,opt)

	// PortworxVolume represents a portworx volume attached and mounted on kubelets host machine
	// +optional
	portworxVolume?: null | #PortworxVolumeSource @go(PortworxVolume,*PortworxVolumeSource) @protobuf(24,bytes,opt)

	// ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
	// +optional
	scaleIO?: null | #ScaleIOVolumeSource @go(ScaleIO,*ScaleIOVolumeSource) @protobuf(25,bytes,opt)

	// StorageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.
	// +optional
	storageos?: null | #StorageOSVolumeSource @go(StorageOS,*StorageOSVolumeSource) @protobuf(27,bytes,opt)

	// CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).
	// +optional
	csi?: null | #CSIVolumeSource @go(CSI,*CSIVolumeSource) @protobuf(28,bytes,opt)

	// 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.
	//
	// +optional
	ephemeral?: null | #EphemeralVolumeSource @go(Ephemeral,*EphemeralVolumeSource) @protobuf(29,bytes,opt)
}

// 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).
#PersistentVolumeClaimVolumeSource: {
	// 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
	claimName: string @go(ClaimName) @protobuf(1,bytes,opt)

	// Will force the ReadOnly setting in VolumeMounts.
	// Default false.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(2,varint,opt)
}

// PersistentVolumeSource is similar to VolumeSource but meant for the
// administrator who creates PVs. Exactly one of its members must be set.
#PersistentVolumeSource: {
	// 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
	// +optional
	gcePersistentDisk?: null | #GCEPersistentDiskVolumeSource @go(GCEPersistentDisk,*GCEPersistentDiskVolumeSource) @protobuf(1,bytes,opt)

	// 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
	// +optional
	awsElasticBlockStore?: null | #AWSElasticBlockStoreVolumeSource @go(AWSElasticBlockStore,*AWSElasticBlockStoreVolumeSource) @protobuf(2,bytes,opt)

	// 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
	// +optional
	hostPath?: null | #HostPathVolumeSource @go(HostPath,*HostPathVolumeSource) @protobuf(3,bytes,opt)

	// 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
	// +optional
	glusterfs?: null | #GlusterfsPersistentVolumeSource @go(Glusterfs,*GlusterfsPersistentVolumeSource) @protobuf(4,bytes,opt)

	// NFS represents an NFS mount on the host. Provisioned by an admin.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
	// +optional
	nfs?: null | #NFSVolumeSource @go(NFS,*NFSVolumeSource) @protobuf(5,bytes,opt)

	// 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
	// +optional
	rbd?: null | #RBDPersistentVolumeSource @go(RBD,*RBDPersistentVolumeSource) @protobuf(6,bytes,opt)

	// 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.
	// +optional
	iscsi?: null | #ISCSIPersistentVolumeSource @go(ISCSI,*ISCSIPersistentVolumeSource) @protobuf(7,bytes,opt)

	// Cinder represents a cinder volume attached and mounted on kubelets host machine.
	// More info: https://examples.k8s.io/mysql-cinder-pd/README.md
	// +optional
	cinder?: null | #CinderPersistentVolumeSource @go(Cinder,*CinderPersistentVolumeSource) @protobuf(8,bytes,opt)

	// CephFS represents a Ceph FS mount on the host that shares a pod's lifetime
	// +optional
	cephfs?: null | #CephFSPersistentVolumeSource @go(CephFS,*CephFSPersistentVolumeSource) @protobuf(9,bytes,opt)

	// FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.
	// +optional
	fc?: null | #FCVolumeSource @go(FC,*FCVolumeSource) @protobuf(10,bytes,opt)

	// 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
	// +optional
	flocker?: null | #FlockerVolumeSource @go(Flocker,*FlockerVolumeSource) @protobuf(11,bytes,opt)

	// FlexVolume represents a generic volume resource that is
	// provisioned/attached using an exec based plugin.
	// +optional
	flexVolume?: null | #FlexPersistentVolumeSource @go(FlexVolume,*FlexPersistentVolumeSource) @protobuf(12,bytes,opt)

	// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
	// +optional
	azureFile?: null | #AzureFilePersistentVolumeSource @go(AzureFile,*AzureFilePersistentVolumeSource) @protobuf(13,bytes,opt)

	// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
	// +optional
	vsphereVolume?: null | #VsphereVirtualDiskVolumeSource @go(VsphereVolume,*VsphereVirtualDiskVolumeSource) @protobuf(14,bytes,opt)

	// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
	// +optional
	quobyte?: null | #QuobyteVolumeSource @go(Quobyte,*QuobyteVolumeSource) @protobuf(15,bytes,opt)

	// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
	// +optional
	azureDisk?: null | #AzureDiskVolumeSource @go(AzureDisk,*AzureDiskVolumeSource) @protobuf(16,bytes,opt)

	// PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine
	photonPersistentDisk?: null | #PhotonPersistentDiskVolumeSource @go(PhotonPersistentDisk,*PhotonPersistentDiskVolumeSource) @protobuf(17,bytes,opt)

	// PortworxVolume represents a portworx volume attached and mounted on kubelets host machine
	// +optional
	portworxVolume?: null | #PortworxVolumeSource @go(PortworxVolume,*PortworxVolumeSource) @protobuf(18,bytes,opt)

	// ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
	// +optional
	scaleIO?: null | #ScaleIOPersistentVolumeSource @go(ScaleIO,*ScaleIOPersistentVolumeSource) @protobuf(19,bytes,opt)

	// Local represents directly-attached storage with node affinity
	// +optional
	local?: null | #LocalVolumeSource @go(Local,*LocalVolumeSource) @protobuf(20,bytes,opt)

	// 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
	// +optional
	storageos?: null | #StorageOSPersistentVolumeSource @go(StorageOS,*StorageOSPersistentVolumeSource) @protobuf(21,bytes,opt)

	// CSI represents storage that is handled by an external CSI driver (Beta feature).
	// +optional
	csi?: null | #CSIPersistentVolumeSource @go(CSI,*CSIPersistentVolumeSource) @protobuf(22,bytes,opt)
}

// BetaStorageClassAnnotation represents the beta/previous StorageClass annotation.
// It's currently still used and will be held for backwards compatibility
#BetaStorageClassAnnotation: "volume.beta.kubernetes.io/storage-class"

// MountOptionAnnotation defines mount option annotation used in PVs
#MountOptionAnnotation: "volume.beta.kubernetes.io/mount-options"

// 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
#PersistentVolume: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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
	// +optional
	spec?: #PersistentVolumeSpec @go(Spec) @protobuf(2,bytes,opt)

	// Status represents the current information/status for the persistent volume.
	// Populated by the system.
	// Read-only.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
	// +optional
	status?: #PersistentVolumeStatus @go(Status) @protobuf(3,bytes,opt)
}

// PersistentVolumeSpec is the specification of a persistent volume.
#PersistentVolumeSpec: {
	// A description of the persistent volume's resources and capacity.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#capacity
	// +optional
	capacity?: #ResourceList @go(Capacity) @protobuf(1,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	#PersistentVolumeSource

	// AccessModes contains all ways the volume can be mounted.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes
	// +optional
	accessModes?: [...#PersistentVolumeAccessMode] @go(AccessModes,[]PersistentVolumeAccessMode) @protobuf(3,bytes,rep,casttype=PersistentVolumeAccessMode)

	// 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
	// +optional
	claimRef?: null | #ObjectReference @go(ClaimRef,*ObjectReference) @protobuf(4,bytes,opt)

	// 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
	// +optional
	persistentVolumeReclaimPolicy?: #PersistentVolumeReclaimPolicy @go(PersistentVolumeReclaimPolicy) @protobuf(5,bytes,opt,casttype=PersistentVolumeReclaimPolicy)

	// Name of StorageClass to which this persistent volume belongs. Empty value
	// means that this volume does not belong to any StorageClass.
	// +optional
	storageClassName?: string @go(StorageClassName) @protobuf(6,bytes,opt)

	// 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
	// +optional
	mountOptions?: [...string] @go(MountOptions,[]string) @protobuf(7,bytes,opt)

	// 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.
	// +optional
	volumeMode?: null | #PersistentVolumeMode @go(VolumeMode,*PersistentVolumeMode) @protobuf(8,bytes,opt,casttype=PersistentVolumeMode)

	// NodeAffinity defines constraints that limit what nodes this volume can be accessed from.
	// This field influences the scheduling of pods that use this volume.
	// +optional
	nodeAffinity?: null | #VolumeNodeAffinity @go(NodeAffinity,*VolumeNodeAffinity) @protobuf(9,bytes,opt)
}

// VolumeNodeAffinity defines constraints that limit what nodes this volume can be accessed from.
#VolumeNodeAffinity: {
	// Required specifies hard node constraints that must be met.
	required?: null | #NodeSelector @go(Required,*NodeSelector) @protobuf(1,bytes,opt)
}

// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes.
// +enum
#PersistentVolumeReclaimPolicy: string // #enumPersistentVolumeReclaimPolicy

#enumPersistentVolumeReclaimPolicy:
	#PersistentVolumeReclaimRecycle |
	#PersistentVolumeReclaimDelete |
	#PersistentVolumeReclaimRetain

// PersistentVolumeReclaimRecycle 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.
#PersistentVolumeReclaimRecycle: #PersistentVolumeReclaimPolicy & "Recycle"

// PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim.
// The volume plugin must support Deletion.
#PersistentVolumeReclaimDelete: #PersistentVolumeReclaimPolicy & "Delete"

// PersistentVolumeReclaimRetain means the volume will be left in its current phase (Released) for manual reclamation by the administrator.
// The default policy is Retain.
#PersistentVolumeReclaimRetain: #PersistentVolumeReclaimPolicy & "Retain"

// PersistentVolumeMode describes how a volume is intended to be consumed, either Block or Filesystem.
// +enum
#PersistentVolumeMode: string // #enumPersistentVolumeMode

#enumPersistentVolumeMode:
	#PersistentVolumeBlock |
	#PersistentVolumeFilesystem

// PersistentVolumeBlock means the volume will not be formatted with a filesystem and will remain a raw block device.
#PersistentVolumeBlock: #PersistentVolumeMode & "Block"

// PersistentVolumeFilesystem means the volume will be or is formatted with a filesystem.
#PersistentVolumeFilesystem: #PersistentVolumeMode & "Filesystem"

// PersistentVolumeStatus is the current status of a persistent volume.
#PersistentVolumeStatus: {
	// Phase indicates if a volume is available, bound to a claim, or released by a claim.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#phase
	// +optional
	phase?: #PersistentVolumePhase @go(Phase) @protobuf(1,bytes,opt,casttype=PersistentVolumePhase)

	// A human-readable message indicating details about why the volume is in this state.
	// +optional
	message?: string @go(Message) @protobuf(2,bytes,opt)

	// Reason is a brief CamelCase string that describes any failure and is meant
	// for machine parsing and tidy display in the CLI.
	// +optional
	reason?: string @go(Reason) @protobuf(3,bytes,opt)
}

// PersistentVolumeList is a list of PersistentVolume items.
#PersistentVolumeList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of persistent volumes.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes
	items: [...#PersistentVolume] @go(Items,[]PersistentVolume) @protobuf(2,bytes,rep)
}

// PersistentVolumeClaim is a user's request for and claim to a persistent volume
#PersistentVolumeClaim: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Spec defines the desired characteristics of a volume requested by a pod author.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
	// +optional
	spec?: #PersistentVolumeClaimSpec @go(Spec) @protobuf(2,bytes,opt)

	// Status represents the current information/status of a persistent volume claim.
	// Read-only.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
	// +optional
	status?: #PersistentVolumeClaimStatus @go(Status) @protobuf(3,bytes,opt)
}

// PersistentVolumeClaimList is a list of PersistentVolumeClaim items.
#PersistentVolumeClaimList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// A list of persistent volume claims.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
	items: [...#PersistentVolumeClaim] @go(Items,[]PersistentVolumeClaim) @protobuf(2,bytes,rep)
}

// PersistentVolumeClaimSpec describes the common attributes of storage devices
// and allows a Source for provider-specific attributes
#PersistentVolumeClaimSpec: {
	// AccessModes contains the desired access modes the volume should have.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
	// +optional
	accessModes?: [...#PersistentVolumeAccessMode] @go(AccessModes,[]PersistentVolumeAccessMode) @protobuf(1,bytes,rep,casttype=PersistentVolumeAccessMode)

	// A label query over volumes to consider for binding.
	// +optional
	selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(4,bytes,opt)

	// 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
	// +optional
	resources?: #ResourceRequirements @go(Resources) @protobuf(2,bytes,opt)

	// VolumeName is the binding reference to the PersistentVolume backing this claim.
	// +optional
	volumeName?: string @go(VolumeName) @protobuf(3,bytes,opt)

	// Name of the StorageClass required by the claim.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
	// +optional
	storageClassName?: null | string @go(StorageClassName,*string) @protobuf(5,bytes,opt)

	// volumeMode defines what type of volume is required by the claim.
	// Value of Filesystem is implied when not included in claim spec.
	// +optional
	volumeMode?: null | #PersistentVolumeMode @go(VolumeMode,*PersistentVolumeMode) @protobuf(6,bytes,opt,casttype=PersistentVolumeMode)

	// 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.
	// +optional
	dataSource?: null | #TypedLocalObjectReference @go(DataSource,*TypedLocalObjectReference) @protobuf(7,bytes,opt)

	// 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.
	// +optional
	dataSourceRef?: null | #TypedLocalObjectReference @go(DataSourceRef,*TypedLocalObjectReference) @protobuf(8,bytes,opt)
}

// PersistentVolumeClaimConditionType is a valid value of PersistentVolumeClaimCondition.Type
// +enum
#PersistentVolumeClaimConditionType: string // #enumPersistentVolumeClaimConditionType

#enumPersistentVolumeClaimConditionType:
	#PersistentVolumeClaimResizing |
	#PersistentVolumeClaimFileSystemResizePending

// PersistentVolumeClaimResizing - a user trigger resize of pvc has been started
#PersistentVolumeClaimResizing: #PersistentVolumeClaimConditionType & "Resizing"

// PersistentVolumeClaimFileSystemResizePending - controller resize is finished and a file system resize is pending on node
#PersistentVolumeClaimFileSystemResizePending: #PersistentVolumeClaimConditionType & "FileSystemResizePending"

// +enum
#PersistentVolumeClaimResizeStatus: string // #enumPersistentVolumeClaimResizeStatus

#enumPersistentVolumeClaimResizeStatus:
	#PersistentVolumeClaimNoExpansionInProgress |
	#PersistentVolumeClaimControllerExpansionInProgress |
	#PersistentVolumeClaimControllerExpansionFailed |
	#PersistentVolumeClaimNodeExpansionPending |
	#PersistentVolumeClaimNodeExpansionInProgress |
	#PersistentVolumeClaimNodeExpansionFailed

// When expansion is complete, the empty string is set by resize controller or kubelet.
#PersistentVolumeClaimNoExpansionInProgress: #PersistentVolumeClaimResizeStatus & ""

// State set when resize controller starts expanding the volume in control-plane
#PersistentVolumeClaimControllerExpansionInProgress: #PersistentVolumeClaimResizeStatus & "ControllerExpansionInProgress"

// State set when expansion has failed in resize controller with a terminal error.
// Transient errors such as timeout should not set this status and should leave ResizeStatus
// unmodified, so as resize controller can resume the volume expansion.
#PersistentVolumeClaimControllerExpansionFailed: #PersistentVolumeClaimResizeStatus & "ControllerExpansionFailed"

// State set when resize controller has finished expanding the volume but further expansion is needed on the node.
#PersistentVolumeClaimNodeExpansionPending: #PersistentVolumeClaimResizeStatus & "NodeExpansionPending"

// State set when kubelet starts expanding the volume.
#PersistentVolumeClaimNodeExpansionInProgress: #PersistentVolumeClaimResizeStatus & "NodeExpansionInProgress"

// State set when expansion has failed in kubelet with a terminal error. Transient errors don't set NodeExpansionFailed.
#PersistentVolumeClaimNodeExpansionFailed: #PersistentVolumeClaimResizeStatus & "NodeExpansionFailed"

// PersistentVolumeClaimCondition contails details about state of pvc
#PersistentVolumeClaimCondition: {
	type:   #PersistentVolumeClaimConditionType @go(Type) @protobuf(1,bytes,opt,casttype=PersistentVolumeClaimConditionType)
	status: #ConditionStatus                    @go(Status) @protobuf(2,bytes,opt,casttype=ConditionStatus)

	// Last time we probed the condition.
	// +optional
	lastProbeTime?: metav1.#Time @go(LastProbeTime) @protobuf(3,bytes,opt)

	// Last time the condition transitioned from one status to another.
	// +optional
	lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(4,bytes,opt)

	// Unique, this should be a short, machine understandable string that gives the reason
	// for condition's last transition. If it reports "ResizeStarted" that means the underlying
	// persistent volume is being resized.
	// +optional
	reason?: string @go(Reason) @protobuf(5,bytes,opt)

	// Human-readable message indicating details about last transition.
	// +optional
	message?: string @go(Message) @protobuf(6,bytes,opt)
}

// PersistentVolumeClaimStatus is the current status of a persistent volume claim.
#PersistentVolumeClaimStatus: {
	// Phase represents the current phase of PersistentVolumeClaim.
	// +optional
	phase?: #PersistentVolumeClaimPhase @go(Phase) @protobuf(1,bytes,opt,casttype=PersistentVolumeClaimPhase)

	// AccessModes contains the actual access modes the volume backing the PVC has.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
	// +optional
	accessModes?: [...#PersistentVolumeAccessMode] @go(AccessModes,[]PersistentVolumeAccessMode) @protobuf(2,bytes,rep,casttype=PersistentVolumeAccessMode)

	// Represents the actual resources of the underlying volume.
	// +optional
	capacity?: #ResourceList @go(Capacity) @protobuf(3,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// Current Condition of persistent volume claim. If underlying persistent volume is being
	// resized then the Condition will be set to 'ResizeStarted'.
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	conditions?: [...#PersistentVolumeClaimCondition] @go(Conditions,[]PersistentVolumeClaimCondition) @protobuf(4,bytes,rep)

	// The storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
	// be larger than the actual capacity when a volume expansion operation is requested.
	// For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
	// If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
	// If a volume expansion capacity request is lowered, allocatedResources is only
	// lowered if there are no expansion operations in progress and if the actual volume capacity
	// is equal or lower than the requested capacity.
	// This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
	// +featureGate=RecoverVolumeExpansionFailure
	// +optional
	allocatedResources?: #ResourceList @go(AllocatedResources) @protobuf(5,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// ResizeStatus stores status of resize operation.
	// ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
	// string by resize controller or kubelet.
	// This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
	// +featureGate=RecoverVolumeExpansionFailure
	// +optional
	resizeStatus?: null | #PersistentVolumeClaimResizeStatus @go(ResizeStatus,*PersistentVolumeClaimResizeStatus) @protobuf(6,bytes,opt,casttype=PersistentVolumeClaimResizeStatus)
}

// +enum
#PersistentVolumeAccessMode: string // #enumPersistentVolumeAccessMode

#enumPersistentVolumeAccessMode:
	#ReadWriteOnce |
	#ReadOnlyMany |
	#ReadWriteMany |
	#ReadWriteOncePod

// can be mounted in read/write mode to exactly 1 host
#ReadWriteOnce: #PersistentVolumeAccessMode & "ReadWriteOnce"

// can be mounted in read-only mode to many hosts
#ReadOnlyMany: #PersistentVolumeAccessMode & "ReadOnlyMany"

// can be mounted in read/write mode to many hosts
#ReadWriteMany: #PersistentVolumeAccessMode & "ReadWriteMany"

// can be mounted in read/write mode to exactly 1 pod
// cannot be used in combination with other access modes
#ReadWriteOncePod: #PersistentVolumeAccessMode & "ReadWriteOncePod"

// +enum
#PersistentVolumePhase: string // #enumPersistentVolumePhase

#enumPersistentVolumePhase:
	#VolumePending |
	#VolumeAvailable |
	#VolumeBound |
	#VolumeReleased |
	#VolumeFailed

// used for PersistentVolumes that are not available
#VolumePending: #PersistentVolumePhase & "Pending"

// used for PersistentVolumes that are not yet bound
// Available volumes are held by the binder and matched to PersistentVolumeClaims
#VolumeAvailable: #PersistentVolumePhase & "Available"

// used for PersistentVolumes that are bound
#VolumeBound: #PersistentVolumePhase & "Bound"

// used for PersistentVolumes where the bound PersistentVolumeClaim was deleted
// released volumes must be recycled before becoming available again
// this phase is used by the persistent volume claim binder to signal to another process to reclaim the resource
#VolumeReleased: #PersistentVolumePhase & "Released"

// used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim
#VolumeFailed: #PersistentVolumePhase & "Failed"

// +enum
#PersistentVolumeClaimPhase: string // #enumPersistentVolumeClaimPhase

#enumPersistentVolumeClaimPhase:
	#ClaimPending |
	#ClaimBound |
	#ClaimLost

// used for PersistentVolumeClaims that are not yet bound
#ClaimPending: #PersistentVolumeClaimPhase & "Pending"

// used for PersistentVolumeClaims that are bound
#ClaimBound: #PersistentVolumeClaimPhase & "Bound"

// used for PersistentVolumeClaims that lost their underlying
// PersistentVolume. The claim was bound to a PersistentVolume and this
// volume does not exist any longer and all data on it was lost.
#ClaimLost: #PersistentVolumeClaimPhase & "Lost"

// +enum
#HostPathType: string // #enumHostPathType

#enumHostPathType:
	#HostPathUnset |
	#HostPathDirectoryOrCreate |
	#HostPathDirectory |
	#HostPathFileOrCreate |
	#HostPathFile |
	#HostPathSocket |
	#HostPathCharDev |
	#HostPathBlockDev

// For backwards compatible, leave it empty if unset
#HostPathUnset: #HostPathType & ""

// If nothing exists at the given path, an empty directory will be created there
// as needed with file mode 0755, having the same group and ownership with Kubelet.
#HostPathDirectoryOrCreate: #HostPathType & "DirectoryOrCreate"

// A directory must exist at the given path
#HostPathDirectory: #HostPathType & "Directory"

// If nothing exists at the given path, an empty file will be created there
// as needed with file mode 0644, having the same group and ownership with Kubelet.
#HostPathFileOrCreate: #HostPathType & "FileOrCreate"

// A file must exist at the given path
#HostPathFile: #HostPathType & "File"

// A UNIX socket must exist at the given path
#HostPathSocket: #HostPathType & "Socket"

// A character device must exist at the given path
#HostPathCharDev: #HostPathType & "CharDevice"

// A block device must exist at the given path
#HostPathBlockDev: #HostPathType & "BlockDevice"

// Represents a host path mapped into a pod.
// Host path volumes do not support ownership management or SELinux relabeling.
#HostPathVolumeSource: {
	// 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
	path: string @go(Path) @protobuf(1,bytes,opt)

	// Type for HostPath Volume
	// Defaults to ""
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
	// +optional
	type?: null | #HostPathType @go(Type,*HostPathType) @protobuf(2,bytes,opt)
}

// Represents an empty directory for a pod.
// Empty directory volumes support ownership management and SELinux relabeling.
#EmptyDirVolumeSource: {
	// 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
	// +optional
	medium?: #StorageMedium @go(Medium) @protobuf(1,bytes,opt,casttype=StorageMedium)

	// 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
	// +optional
	sizeLimit?: null | resource.#Quantity @go(SizeLimit,*resource.Quantity) @protobuf(2,bytes,opt)
}

// Represents a Glusterfs mount that lasts the lifetime of a pod.
// Glusterfs volumes do not support ownership management or SELinux relabeling.
#GlusterfsVolumeSource: {
	// EndpointsName is the endpoint name that details Glusterfs topology.
	// More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
	endpoints: string @go(EndpointsName) @protobuf(1,bytes,opt)

	// Path is the Glusterfs volume path.
	// More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
	path: string @go(Path) @protobuf(2,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)
}

// Represents a Glusterfs mount that lasts the lifetime of a pod.
// Glusterfs volumes do not support ownership management or SELinux relabeling.
#GlusterfsPersistentVolumeSource: {
	// EndpointsName is the endpoint name that details Glusterfs topology.
	// More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
	endpoints: string @go(EndpointsName) @protobuf(1,bytes,opt)

	// Path is the Glusterfs volume path.
	// More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
	path: string @go(Path) @protobuf(2,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)

	// 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
	// +optional
	endpointsNamespace?: null | string @go(EndpointsNamespace,*string) @protobuf(4,bytes,opt)
}

// Represents a Rados Block Device mount that lasts the lifetime of a pod.
// RBD volumes support ownership management and SELinux relabeling.
#RBDVolumeSource: {
	// A collection of Ceph monitors.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	monitors: [...string] @go(CephMonitors,[]string) @protobuf(1,bytes,rep)

	// The rados image name.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	image: string @go(RBDImage) @protobuf(2,bytes,opt)

	// 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
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(3,bytes,opt)

	// The rados pool name.
	// Default is rbd.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	// +optional
	pool?: string @go(RBDPool) @protobuf(4,bytes,opt)

	// The rados user name.
	// Default is admin.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	// +optional
	user?: string @go(RadosUser) @protobuf(5,bytes,opt)

	// 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
	// +optional
	keyring?: string @go(Keyring) @protobuf(6,bytes,opt)

	// 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
	// +optional
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(7,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(8,varint,opt)
}

// Represents a Rados Block Device mount that lasts the lifetime of a pod.
// RBD volumes support ownership management and SELinux relabeling.
#RBDPersistentVolumeSource: {
	// A collection of Ceph monitors.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	monitors: [...string] @go(CephMonitors,[]string) @protobuf(1,bytes,rep)

	// The rados image name.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	image: string @go(RBDImage) @protobuf(2,bytes,opt)

	// 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
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(3,bytes,opt)

	// The rados pool name.
	// Default is rbd.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	// +optional
	pool?: string @go(RBDPool) @protobuf(4,bytes,opt)

	// The rados user name.
	// Default is admin.
	// More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
	// +optional
	user?: string @go(RadosUser) @protobuf(5,bytes,opt)

	// 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
	// +optional
	keyring?: string @go(Keyring) @protobuf(6,bytes,opt)

	// 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
	// +optional
	secretRef?: null | #SecretReference @go(SecretRef,*SecretReference) @protobuf(7,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(8,varint,opt)
}

// 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.
#CinderVolumeSource: {
	// volume id used to identify the volume in cinder.
	// More info: https://examples.k8s.io/mysql-cinder-pd/README.md
	volumeID: string @go(VolumeID) @protobuf(1,bytes,opt)

	// 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
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)

	// Optional: points to a secret object containing parameters used to connect
	// to OpenStack.
	// +optional
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(4,bytes,opt)
}

// 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.
#CinderPersistentVolumeSource: {
	// volume id used to identify the volume in cinder.
	// More info: https://examples.k8s.io/mysql-cinder-pd/README.md
	volumeID: string @go(VolumeID) @protobuf(1,bytes,opt)

	// 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
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)

	// Optional: points to a secret object containing parameters used to connect
	// to OpenStack.
	// +optional
	secretRef?: null | #SecretReference @go(SecretRef,*SecretReference) @protobuf(4,bytes,opt)
}

// Represents a Ceph Filesystem mount that lasts the lifetime of a pod
// Cephfs volumes do not support ownership management or SELinux relabeling.
#CephFSVolumeSource: {
	// Required: Monitors is a collection of Ceph monitors
	// More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
	monitors: [...string] @go(Monitors,[]string) @protobuf(1,bytes,rep)

	// Optional: Used as the mounted root, rather than the full Ceph tree, default is /
	// +optional
	path?: string @go(Path) @protobuf(2,bytes,opt)

	// Optional: User is the rados user name, default is admin
	// More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
	// +optional
	user?: string @go(User) @protobuf(3,bytes,opt)

	// 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
	// +optional
	secretFile?: string @go(SecretFile) @protobuf(4,bytes,opt)

	// 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
	// +optional
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(5,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(6,varint,opt)
}

// SecretReference represents a Secret Reference. It has enough information to retrieve secret
// in any namespace
// +structType=atomic
#SecretReference: {
	// Name is unique within a namespace to reference a secret resource.
	// +optional
	name?: string @go(Name) @protobuf(1,bytes,opt)

	// Namespace defines the space within which the secret name must be unique.
	// +optional
	namespace?: string @go(Namespace) @protobuf(2,bytes,opt)
}

// Represents a Ceph Filesystem mount that lasts the lifetime of a pod
// Cephfs volumes do not support ownership management or SELinux relabeling.
#CephFSPersistentVolumeSource: {
	// Required: Monitors is a collection of Ceph monitors
	// More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
	monitors: [...string] @go(Monitors,[]string) @protobuf(1,bytes,rep)

	// Optional: Used as the mounted root, rather than the full Ceph tree, default is /
	// +optional
	path?: string @go(Path) @protobuf(2,bytes,opt)

	// Optional: User is the rados user name, default is admin
	// More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it
	// +optional
	user?: string @go(User) @protobuf(3,bytes,opt)

	// 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
	// +optional
	secretFile?: string @go(SecretFile) @protobuf(4,bytes,opt)

	// 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
	// +optional
	secretRef?: null | #SecretReference @go(SecretRef,*SecretReference) @protobuf(5,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(6,varint,opt)
}

// 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.
#FlockerVolumeSource: {
	// Name of the dataset stored as metadata -> name on the dataset for Flocker
	// should be considered as deprecated
	// +optional
	datasetName?: string @go(DatasetName) @protobuf(1,bytes,opt)

	// UUID of the dataset. This is unique identifier of a Flocker dataset
	// +optional
	datasetUUID?: string @go(DatasetUUID) @protobuf(2,bytes,opt)
}

// StorageMedium defines ways that storage can be allocated to a volume.
#StorageMedium: string // #enumStorageMedium

#enumStorageMedium:
	#StorageMediumDefault |
	#StorageMediumMemory |
	#StorageMediumHugePages |
	#StorageMediumHugePagesPrefix

#StorageMediumDefault:         #StorageMedium & ""
#StorageMediumMemory:          #StorageMedium & "Memory"
#StorageMediumHugePages:       #StorageMedium & "HugePages"
#StorageMediumHugePagesPrefix: #StorageMedium & "HugePages-"

// Protocol defines network protocols supported for things like container ports.
// +enum
#Protocol: string // #enumProtocol

#enumProtocol:
	#ProtocolTCP |
	#ProtocolUDP |
	#ProtocolSCTP

// ProtocolTCP is the TCP protocol.
#ProtocolTCP: #Protocol & "TCP"

// ProtocolUDP is the UDP protocol.
#ProtocolUDP: #Protocol & "UDP"

// ProtocolSCTP is the SCTP protocol.
#ProtocolSCTP: #Protocol & "SCTP"

// 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.
#GCEPersistentDiskVolumeSource: {
	// 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
	pdName: string @go(PDName) @protobuf(1,bytes,opt)

	// 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
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// 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
	// +optional
	partition?: int32 @go(Partition) @protobuf(3,varint,opt)

	// ReadOnly here will force the ReadOnly setting in VolumeMounts.
	// Defaults to false.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)
}

// Represents a Quobyte mount that lasts the lifetime of a pod.
// Quobyte volumes do not support ownership management or SELinux relabeling.
#QuobyteVolumeSource: {
	// 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
	registry: string @go(Registry) @protobuf(1,bytes,opt)

	// Volume is a string that references an already created Quobyte volume by name.
	volume: string @go(Volume) @protobuf(2,bytes,opt)

	// ReadOnly here will force the Quobyte volume to be mounted with read-only permissions.
	// Defaults to false.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)

	// User to map volume access to
	// Defaults to serivceaccount user
	// +optional
	user?: string @go(User) @protobuf(4,bytes,opt)

	// Group to map volume access to
	// Default is no group
	// +optional
	group?: string @go(Group) @protobuf(5,bytes,opt)

	// Tenant owning the given Quobyte volume in the Backend
	// Used with dynamically provisioned Quobyte volumes, value is set by the plugin
	// +optional
	tenant?: string @go(Tenant) @protobuf(6,bytes,opt)
}

// FlexPersistentVolumeSource represents a generic persistent volume resource that is
// provisioned/attached using an exec based plugin.
#FlexPersistentVolumeSource: {
	// Driver is the name of the driver to use for this volume.
	driver: string @go(Driver) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	secretRef?: null | #SecretReference @go(SecretRef,*SecretReference) @protobuf(3,bytes,opt)

	// Optional: Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)

	// Optional: Extra command options if any.
	// +optional
	options?: {[string]: string} @go(Options,map[string]string) @protobuf(5,bytes,rep)
}

// FlexVolume represents a generic volume resource that is
// provisioned/attached using an exec based plugin.
#FlexVolumeSource: {
	// Driver is the name of the driver to use for this volume.
	driver: string @go(Driver) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(3,bytes,opt)

	// Optional: Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)

	// Optional: Extra command options if any.
	// +optional
	options?: {[string]: string} @go(Options,map[string]string) @protobuf(5,bytes,rep)
}

// 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.
#AWSElasticBlockStoreVolumeSource: {
	// Unique ID of the persistent disk resource in AWS (Amazon EBS volume).
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
	volumeID: string @go(VolumeID) @protobuf(1,bytes,opt)

	// 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
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// 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).
	// +optional
	partition?: int32 @go(Partition) @protobuf(3,varint,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)
}

// 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.
#GitRepoVolumeSource: {
	// Repository URL
	repository: string @go(Repository) @protobuf(1,bytes,opt)

	// Commit hash for the specified revision.
	// +optional
	revision?: string @go(Revision) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	directory?: string @go(Directory) @protobuf(3,bytes,opt)
}

// 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.
#SecretVolumeSource: {
	// Name of the secret in the pod's namespace to use.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#secret
	// +optional
	secretName?: string @go(SecretName) @protobuf(1,bytes,opt)

	// 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 '..'.
	// +optional
	items?: [...#KeyToPath] @go(Items,[]KeyToPath) @protobuf(2,bytes,rep)

	// 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.
	// +optional
	defaultMode?: null | int32 @go(DefaultMode,*int32) @protobuf(3,bytes,opt)

	// Specify whether the Secret or its keys must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(4,varint,opt)
}

#SecretVolumeSourceDefaultMode: int32 & 0o644

// 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.
#SecretProjection: {
	#LocalObjectReference

	// 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 '..'.
	// +optional
	items?: [...#KeyToPath] @go(Items,[]KeyToPath) @protobuf(2,bytes,rep)

	// Specify whether the Secret or its key must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(4,varint,opt)
}

// Represents an NFS mount that lasts the lifetime of a pod.
// NFS volumes do not support ownership management or SELinux relabeling.
#NFSVolumeSource: {
	// Server is the hostname or IP address of the NFS server.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
	server: string @go(Server) @protobuf(1,bytes,opt)

	// Path that is exported by the NFS server.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
	path: string @go(Path) @protobuf(2,bytes,opt)

	// 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
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)
}

// Represents an ISCSI disk.
// ISCSI volumes can only be mounted as read/write once.
// ISCSI volumes support ownership management and SELinux relabeling.
#ISCSIVolumeSource: {
	// 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).
	targetPortal: string @go(TargetPortal) @protobuf(1,bytes,opt)

	// Target iSCSI Qualified Name.
	iqn: string @go(IQN) @protobuf(2,bytes,opt)

	// iSCSI Target Lun number.
	lun: int32 @go(Lun) @protobuf(3,varint,opt)

	// iSCSI Interface Name that uses an iSCSI transport.
	// Defaults to 'default' (tcp).
	// +optional
	iscsiInterface?: string @go(ISCSIInterface) @protobuf(4,bytes,opt)

	// 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
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(5,bytes,opt)

	// ReadOnly here will force the ReadOnly setting in VolumeMounts.
	// Defaults to false.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(6,varint,opt)

	// 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).
	// +optional
	portals?: [...string] @go(Portals,[]string) @protobuf(7,bytes,opt)

	// whether support iSCSI Discovery CHAP authentication
	// +optional
	chapAuthDiscovery?: bool @go(DiscoveryCHAPAuth) @protobuf(8,varint,opt)

	// whether support iSCSI Session CHAP authentication
	// +optional
	chapAuthSession?: bool @go(SessionCHAPAuth) @protobuf(11,varint,opt)

	// CHAP Secret for iSCSI target and initiator authentication
	// +optional
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(10,bytes,opt)

	// Custom iSCSI Initiator Name.
	// If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface
	// <target portal>:<volume name> will be created for the connection.
	// +optional
	initiatorName?: null | string @go(InitiatorName,*string) @protobuf(12,bytes,opt)
}

// ISCSIPersistentVolumeSource represents an ISCSI disk.
// ISCSI volumes can only be mounted as read/write once.
// ISCSI volumes support ownership management and SELinux relabeling.
#ISCSIPersistentVolumeSource: {
	// 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).
	targetPortal: string @go(TargetPortal) @protobuf(1,bytes,opt)

	// Target iSCSI Qualified Name.
	iqn: string @go(IQN) @protobuf(2,bytes,opt)

	// iSCSI Target Lun number.
	lun: int32 @go(Lun) @protobuf(3,varint,opt)

	// iSCSI Interface Name that uses an iSCSI transport.
	// Defaults to 'default' (tcp).
	// +optional
	iscsiInterface?: string @go(ISCSIInterface) @protobuf(4,bytes,opt)

	// 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
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(5,bytes,opt)

	// ReadOnly here will force the ReadOnly setting in VolumeMounts.
	// Defaults to false.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(6,varint,opt)

	// 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).
	// +optional
	portals?: [...string] @go(Portals,[]string) @protobuf(7,bytes,opt)

	// whether support iSCSI Discovery CHAP authentication
	// +optional
	chapAuthDiscovery?: bool @go(DiscoveryCHAPAuth) @protobuf(8,varint,opt)

	// whether support iSCSI Session CHAP authentication
	// +optional
	chapAuthSession?: bool @go(SessionCHAPAuth) @protobuf(11,varint,opt)

	// CHAP Secret for iSCSI target and initiator authentication
	// +optional
	secretRef?: null | #SecretReference @go(SecretRef,*SecretReference) @protobuf(10,bytes,opt)

	// Custom iSCSI Initiator Name.
	// If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface
	// <target portal>:<volume name> will be created for the connection.
	// +optional
	initiatorName?: null | string @go(InitiatorName,*string) @protobuf(12,bytes,opt)
}

// 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.
#FCVolumeSource: {
	// Optional: FC target worldwide names (WWNs)
	// +optional
	targetWWNs?: [...string] @go(TargetWWNs,[]string) @protobuf(1,bytes,rep)

	// Optional: FC target lun number
	// +optional
	lun?: null | int32 @go(Lun,*int32) @protobuf(2,varint,opt)

	// 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.
	// TODO: how do we prevent errors in the filesystem from compromising the machine
	// +optional
	fsType?: string @go(FSType) @protobuf(3,bytes,opt)

	// Optional: Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)

	// Optional: FC volume world wide identifiers (wwids)
	// Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.
	// +optional
	wwids?: [...string] @go(WWIDs,[]string) @protobuf(5,bytes,rep)
}

// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
#AzureFileVolumeSource: {
	// the name of secret that contains Azure Storage Account Name and Key
	secretName: string @go(SecretName) @protobuf(1,bytes,opt)

	// Share Name
	shareName: string @go(ShareName) @protobuf(2,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)
}

// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
#AzureFilePersistentVolumeSource: {
	// the name of secret that contains Azure Storage Account Name and Key
	secretName: string @go(SecretName) @protobuf(1,bytes,opt)

	// Share Name
	shareName: string @go(ShareName) @protobuf(2,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)

	// the namespace of the secret that contains Azure Storage Account Name and Key
	// default is the same as the Pod
	// +optional
	secretNamespace?: null | string @go(SecretNamespace,*string) @protobuf(4,bytes,opt)
}

// Represents a vSphere volume resource.
#VsphereVirtualDiskVolumeSource: {
	// Path that identifies vSphere volume vmdk
	volumePath: string @go(VolumePath) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// Storage Policy Based Management (SPBM) profile name.
	// +optional
	storagePolicyName?: string @go(StoragePolicyName) @protobuf(3,bytes,opt)

	// Storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.
	// +optional
	storagePolicyID?: string @go(StoragePolicyID) @protobuf(4,bytes,opt)
}

// Represents a Photon Controller persistent disk resource.
#PhotonPersistentDiskVolumeSource: {
	// ID that identifies Photon Controller persistent disk
	pdID: string @go(PdID) @protobuf(1,bytes,opt)

	// 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.
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)
}

// +enum
#AzureDataDiskCachingMode: string // #enumAzureDataDiskCachingMode

#enumAzureDataDiskCachingMode:
	#AzureDataDiskCachingNone |
	#AzureDataDiskCachingReadOnly |
	#AzureDataDiskCachingReadWrite

// +enum
#AzureDataDiskKind: string // #enumAzureDataDiskKind

#enumAzureDataDiskKind:
	#AzureSharedBlobDisk |
	#AzureDedicatedBlobDisk |
	#AzureManagedDisk

#AzureDataDiskCachingNone:      #AzureDataDiskCachingMode & "None"
#AzureDataDiskCachingReadOnly:  #AzureDataDiskCachingMode & "ReadOnly"
#AzureDataDiskCachingReadWrite: #AzureDataDiskCachingMode & "ReadWrite"
#AzureSharedBlobDisk:           #AzureDataDiskKind & "Shared"
#AzureDedicatedBlobDisk:        #AzureDataDiskKind & "Dedicated"
#AzureManagedDisk:              #AzureDataDiskKind & "Managed"

// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
#AzureDiskVolumeSource: {
	// The Name of the data disk in the blob storage
	diskName: string @go(DiskName) @protobuf(1,bytes,opt)

	// The URI the data disk in the blob storage
	diskURI: string @go(DataDiskURI) @protobuf(2,bytes,opt)

	// Host Caching mode: None, Read Only, Read Write.
	// +optional
	cachingMode?: null | #AzureDataDiskCachingMode @go(CachingMode,*AzureDataDiskCachingMode) @protobuf(3,bytes,opt,casttype=AzureDataDiskCachingMode)

	// 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.
	// +optional
	fsType?: null | string @go(FSType,*string) @protobuf(4,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: null | bool @go(ReadOnly,*bool) @protobuf(5,varint,opt)

	// 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
	kind?: null | #AzureDataDiskKind @go(Kind,*AzureDataDiskKind) @protobuf(6,bytes,opt,casttype=AzureDataDiskKind)
}

// PortworxVolumeSource represents a Portworx volume resource.
#PortworxVolumeSource: {
	// VolumeID uniquely identifies a Portworx volume
	volumeID: string @go(VolumeID) @protobuf(1,bytes,opt)

	// 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.
	fsType?: string @go(FSType) @protobuf(2,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)
}

// ScaleIOVolumeSource represents a persistent ScaleIO volume
#ScaleIOVolumeSource: {
	// The host address of the ScaleIO API Gateway.
	gateway: string @go(Gateway) @protobuf(1,bytes,opt)

	// The name of the storage system as configured in ScaleIO.
	system: string @go(System) @protobuf(2,bytes,opt)

	// SecretRef references to the secret for ScaleIO user and other
	// sensitive information. If this is not provided, Login operation will fail.
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(3,bytes,opt)

	// Flag to enable/disable SSL communication with Gateway, default false
	// +optional
	sslEnabled?: bool @go(SSLEnabled) @protobuf(4,varint,opt)

	// The name of the ScaleIO Protection Domain for the configured storage.
	// +optional
	protectionDomain?: string @go(ProtectionDomain) @protobuf(5,bytes,opt)

	// The ScaleIO Storage Pool associated with the protection domain.
	// +optional
	storagePool?: string @go(StoragePool) @protobuf(6,bytes,opt)

	// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
	// Default is ThinProvisioned.
	// +optional
	storageMode?: string @go(StorageMode) @protobuf(7,bytes,opt)

	// The name of a volume already created in the ScaleIO system
	// that is associated with this volume source.
	volumeName?: string @go(VolumeName) @protobuf(8,bytes,opt)

	// Filesystem type to mount.
	// Must be a filesystem type supported by the host operating system.
	// Ex. "ext4", "xfs", "ntfs".
	// Default is "xfs".
	// +optional
	fsType?: string @go(FSType) @protobuf(9,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(10,varint,opt)
}

// ScaleIOPersistentVolumeSource represents a persistent ScaleIO volume
#ScaleIOPersistentVolumeSource: {
	// The host address of the ScaleIO API Gateway.
	gateway: string @go(Gateway) @protobuf(1,bytes,opt)

	// The name of the storage system as configured in ScaleIO.
	system: string @go(System) @protobuf(2,bytes,opt)

	// SecretRef references to the secret for ScaleIO user and other
	// sensitive information. If this is not provided, Login operation will fail.
	secretRef?: null | #SecretReference @go(SecretRef,*SecretReference) @protobuf(3,bytes,opt)

	// Flag to enable/disable SSL communication with Gateway, default false
	// +optional
	sslEnabled?: bool @go(SSLEnabled) @protobuf(4,varint,opt)

	// The name of the ScaleIO Protection Domain for the configured storage.
	// +optional
	protectionDomain?: string @go(ProtectionDomain) @protobuf(5,bytes,opt)

	// The ScaleIO Storage Pool associated with the protection domain.
	// +optional
	storagePool?: string @go(StoragePool) @protobuf(6,bytes,opt)

	// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
	// Default is ThinProvisioned.
	// +optional
	storageMode?: string @go(StorageMode) @protobuf(7,bytes,opt)

	// The name of a volume already created in the ScaleIO system
	// that is associated with this volume source.
	volumeName?: string @go(VolumeName) @protobuf(8,bytes,opt)

	// Filesystem type to mount.
	// Must be a filesystem type supported by the host operating system.
	// Ex. "ext4", "xfs", "ntfs".
	// Default is "xfs"
	// +optional
	fsType?: string @go(FSType) @protobuf(9,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(10,varint,opt)
}

// Represents a StorageOS persistent volume resource.
#StorageOSVolumeSource: {
	// VolumeName is the human-readable name of the StorageOS volume.  Volume
	// names are only unique within a namespace.
	volumeName?: string @go(VolumeName) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	volumeNamespace?: string @go(VolumeNamespace) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	fsType?: string @go(FSType) @protobuf(3,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)

	// SecretRef specifies the secret to use for obtaining the StorageOS API
	// credentials.  If not specified, default values will be attempted.
	// +optional
	secretRef?: null | #LocalObjectReference @go(SecretRef,*LocalObjectReference) @protobuf(5,bytes,opt)
}

// Represents a StorageOS persistent volume resource.
#StorageOSPersistentVolumeSource: {
	// VolumeName is the human-readable name of the StorageOS volume.  Volume
	// names are only unique within a namespace.
	volumeName?: string @go(VolumeName) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	volumeNamespace?: string @go(VolumeNamespace) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	fsType?: string @go(FSType) @protobuf(3,bytes,opt)

	// Defaults to false (read/write). ReadOnly here will force
	// the ReadOnly setting in VolumeMounts.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(4,varint,opt)

	// SecretRef specifies the secret to use for obtaining the StorageOS API
	// credentials.  If not specified, default values will be attempted.
	// +optional
	secretRef?: null | #ObjectReference @go(SecretRef,*ObjectReference) @protobuf(5,bytes,opt)
}

// 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.
#ConfigMapVolumeSource: {
	#LocalObjectReference

	// 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 '..'.
	// +optional
	items?: [...#KeyToPath] @go(Items,[]KeyToPath) @protobuf(2,bytes,rep)

	// 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.
	// +optional
	defaultMode?: null | int32 @go(DefaultMode,*int32) @protobuf(3,varint,opt)

	// Specify whether the ConfigMap or its keys must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(4,varint,opt)
}

#ConfigMapVolumeSourceDefaultMode: int32 & 0o644

// 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.
#ConfigMapProjection: {
	#LocalObjectReference

	// 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 '..'.
	// +optional
	items?: [...#KeyToPath] @go(Items,[]KeyToPath) @protobuf(2,bytes,rep)

	// Specify whether the ConfigMap or its keys must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(4,varint,opt)
}

// 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).
#ServiceAccountTokenProjection: {
	// 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.
	//+optional
	audience?: string @go(Audience) @protobuf(1,bytes,rep)

	// 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.
	//+optional
	expirationSeconds?: null | int64 @go(ExpirationSeconds,*int64) @protobuf(2,varint,opt)

	// Path is the path relative to the mount point of the file to project the
	// token into.
	path: string @go(Path) @protobuf(3,bytes,opt)
}

// Represents a projected volume source
#ProjectedVolumeSource: {
	// list of volume projections
	// +optional
	sources: [...#VolumeProjection] @go(Sources,[]VolumeProjection) @protobuf(1,bytes,rep)

	// 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.
	// +optional
	defaultMode?: null | int32 @go(DefaultMode,*int32) @protobuf(2,varint,opt)
}

// Projection that may be projected along with other supported volume types
#VolumeProjection: {
	// information about the secret data to project
	// +optional
	secret?: null | #SecretProjection @go(Secret,*SecretProjection) @protobuf(1,bytes,opt)

	// information about the downwardAPI data to project
	// +optional
	downwardAPI?: null | #DownwardAPIProjection @go(DownwardAPI,*DownwardAPIProjection) @protobuf(2,bytes,opt)

	// information about the configMap data to project
	// +optional
	configMap?: null | #ConfigMapProjection @go(ConfigMap,*ConfigMapProjection) @protobuf(3,bytes,opt)

	// information about the serviceAccountToken data to project
	// +optional
	serviceAccountToken?: null | #ServiceAccountTokenProjection @go(ServiceAccountToken,*ServiceAccountTokenProjection) @protobuf(4,bytes,opt)
}

#ProjectedVolumeSourceDefaultMode: int32 & 0o644

// Maps a string key to a path within a volume.
#KeyToPath: {
	// The key to project.
	key: string @go(Key) @protobuf(1,bytes,opt)

	// 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 '..'.
	path: string @go(Path) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	mode?: null | int32 @go(Mode,*int32) @protobuf(3,varint,opt)
}

// Local represents directly-attached storage with node affinity (Beta feature)
#LocalVolumeSource: {
	// The full path to the volume on the node.
	// It can be either a directory or block device (disk, partition, ...).
	path: string @go(Path) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	fsType?: null | string @go(FSType,*string) @protobuf(2,bytes,opt)
}

// Represents storage that is managed by an external CSI volume driver (Beta feature)
#CSIPersistentVolumeSource: {
	// Driver is the name of the driver to use for this volume.
	// Required.
	driver: string @go(Driver) @protobuf(1,bytes,opt)

	// VolumeHandle is the unique volume name returned by the CSI volume
	// plugin’s CreateVolume to refer to the volume on all subsequent calls.
	// Required.
	volumeHandle: string @go(VolumeHandle) @protobuf(2,bytes,opt)

	// Optional: The value to pass to ControllerPublishVolumeRequest.
	// Defaults to false (read/write).
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(3,varint,opt)

	// Filesystem type to mount.
	// Must be a filesystem type supported by the host operating system.
	// Ex. "ext4", "xfs", "ntfs".
	// +optional
	fsType?: string @go(FSType) @protobuf(4,bytes,opt)

	// Attributes of the volume to publish.
	// +optional
	volumeAttributes?: {[string]: string} @go(VolumeAttributes,map[string]string) @protobuf(5,bytes,rep)

	// 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.
	// +optional
	controllerPublishSecretRef?: null | #SecretReference @go(ControllerPublishSecretRef,*SecretReference) @protobuf(6,bytes,opt)

	// 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.
	// +optional
	nodeStageSecretRef?: null | #SecretReference @go(NodeStageSecretRef,*SecretReference) @protobuf(7,bytes,opt)

	// 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.
	// +optional
	nodePublishSecretRef?: null | #SecretReference @go(NodePublishSecretRef,*SecretReference) @protobuf(8,bytes,opt)

	// 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.
	// +optional
	controllerExpandSecretRef?: null | #SecretReference @go(ControllerExpandSecretRef,*SecretReference) @protobuf(9,bytes,opt)
}

// Represents a source location of a volume to mount, managed by an external CSI driver
#CSIVolumeSource: {
	// 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.
	driver: string @go(Driver) @protobuf(1,bytes,opt)

	// Specifies a read-only configuration for the volume.
	// Defaults to false (read/write).
	// +optional
	readOnly?: null | bool @go(ReadOnly,*bool) @protobuf(2,varint,opt)

	// 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.
	// +optional
	fsType?: null | string @go(FSType,*string) @protobuf(3,bytes,opt)

	// VolumeAttributes stores driver-specific properties that are passed to the CSI
	// driver. Consult your driver's documentation for supported values.
	// +optional
	volumeAttributes?: {[string]: string} @go(VolumeAttributes,map[string]string) @protobuf(4,bytes,rep)

	// 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.
	// +optional
	nodePublishSecretRef?: null | #LocalObjectReference @go(NodePublishSecretRef,*LocalObjectReference) @protobuf(5,bytes,opt)
}

// Represents an ephemeral volume that is handled by a normal storage driver.
#EphemeralVolumeSource: {
	// 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.
	volumeClaimTemplate?: null | #PersistentVolumeClaimTemplate @go(VolumeClaimTemplate,*PersistentVolumeClaimTemplate) @protobuf(1,bytes,opt)
}

// PersistentVolumeClaimTemplate is used to produce
// PersistentVolumeClaim objects as part of an EphemeralVolumeSource.
#PersistentVolumeClaimTemplate: {
	// 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.
	//
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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.
	spec: #PersistentVolumeClaimSpec @go(Spec) @protobuf(2,bytes)
}

// ContainerPort represents a network port in a single container.
#ContainerPort: {
	// 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.
	// +optional
	name?: string @go(Name) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	hostPort?: int32 @go(HostPort) @protobuf(2,varint,opt)

	// Number of port to expose on the pod's IP address.
	// This must be a valid port number, 0 < x < 65536.
	containerPort: int32 @go(ContainerPort) @protobuf(3,varint,opt)

	// Protocol for port. Must be UDP, TCP, or SCTP.
	// Defaults to "TCP".
	// +optional
	// +default="TCP"
	protocol?: #Protocol @go(Protocol) @protobuf(4,bytes,opt,casttype=Protocol)

	// What host IP to bind the external port to.
	// +optional
	hostIP?: string @go(HostIP) @protobuf(5,bytes,opt)
}

// VolumeMount describes a mounting of a Volume within a container.
#VolumeMount: {
	// This must match the Name of a Volume.
	name: string @go(Name) @protobuf(1,bytes,opt)

	// Mounted read-only if true, read-write otherwise (false or unspecified).
	// Defaults to false.
	// +optional
	readOnly?: bool @go(ReadOnly) @protobuf(2,varint,opt)

	// Path within the container at which the volume should be mounted.  Must
	// not contain ':'.
	mountPath: string @go(MountPath) @protobuf(3,bytes,opt)

	// Path within the volume from which the container's volume should be mounted.
	// Defaults to "" (volume's root).
	// +optional
	subPath?: string @go(SubPath) @protobuf(4,bytes,opt)

	// 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.
	// +optional
	mountPropagation?: null | #MountPropagationMode @go(MountPropagation,*MountPropagationMode) @protobuf(5,bytes,opt,casttype=MountPropagationMode)

	// 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.
	// +optional
	subPathExpr?: string @go(SubPathExpr) @protobuf(6,bytes,opt)
}

// MountPropagationMode describes mount propagation.
// +enum
#MountPropagationMode: string // #enumMountPropagationMode

#enumMountPropagationMode:
	#MountPropagationNone |
	#MountPropagationHostToContainer |
	#MountPropagationBidirectional

// MountPropagationNone means that the volume in a container will
// not receive new mounts from the host or other containers, and filesystems
// mounted inside the container won't be propagated to the host or other
// containers.
// Note that this mode corresponds to "private" in Linux terminology.
#MountPropagationNone: #MountPropagationMode & "None"

// MountPropagationHostToContainer means that the volume in a container will
// receive new mounts from the host or other containers, but filesystems
// mounted inside the container won't be propagated to the host or other
// containers.
// Note that this mode is recursively applied to all mounts in the volume
// ("rslave" in Linux terminology).
#MountPropagationHostToContainer: #MountPropagationMode & "HostToContainer"

// MountPropagationBidirectional means that the volume in a container will
// receive new mounts from the host or other containers, and its own mounts
// will be propagated from the container to the host or other containers.
// Note that this mode is recursively applied to all mounts in the volume
// ("rshared" in Linux terminology).
#MountPropagationBidirectional: #MountPropagationMode & "Bidirectional"

// volumeDevice describes a mapping of a raw block device within a container.
#VolumeDevice: {
	// name must match the name of a persistentVolumeClaim in the pod
	name: string @go(Name) @protobuf(1,bytes,opt)

	// devicePath is the path inside of the container that the device will be mapped to.
	devicePath: string @go(DevicePath) @protobuf(2,bytes,opt)
}

// EnvVar represents an environment variable present in a Container.
#EnvVar: {
	// Name of the environment variable. Must be a C_IDENTIFIER.
	name: string @go(Name) @protobuf(1,bytes,opt)

	// 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 "".
	// +optional
	value?: string @go(Value) @protobuf(2,bytes,opt)

	// Source for the environment variable's value. Cannot be used if value is not empty.
	// +optional
	valueFrom?: null | #EnvVarSource @go(ValueFrom,*EnvVarSource) @protobuf(3,bytes,opt)
}

// EnvVarSource represents a source for the value of an EnvVar.
#EnvVarSource: {
	// 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.
	// +optional
	fieldRef?: null | #ObjectFieldSelector @go(FieldRef,*ObjectFieldSelector) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	resourceFieldRef?: null | #ResourceFieldSelector @go(ResourceFieldRef,*ResourceFieldSelector) @protobuf(2,bytes,opt)

	// Selects a key of a ConfigMap.
	// +optional
	configMapKeyRef?: null | #ConfigMapKeySelector @go(ConfigMapKeyRef,*ConfigMapKeySelector) @protobuf(3,bytes,opt)

	// Selects a key of a secret in the pod's namespace
	// +optional
	secretKeyRef?: null | #SecretKeySelector @go(SecretKeyRef,*SecretKeySelector) @protobuf(4,bytes,opt)
}

// ObjectFieldSelector selects an APIVersioned field of an object.
// +structType=atomic
#ObjectFieldSelector: {
	// Version of the schema the FieldPath is written in terms of, defaults to "v1".
	// +optional
	apiVersion?: string @go(APIVersion) @protobuf(1,bytes,opt)

	// Path of the field to select in the specified API version.
	fieldPath: string @go(FieldPath) @protobuf(2,bytes,opt)
}

// ResourceFieldSelector represents container resources (cpu, memory) and their output format
// +structType=atomic
#ResourceFieldSelector: {
	// Container name: required for volumes, optional for env vars
	// +optional
	containerName?: string @go(ContainerName) @protobuf(1,bytes,opt)

	// Required: resource to select
	"resource": string @go(Resource) @protobuf(2,bytes,opt)

	// Specifies the output format of the exposed resources, defaults to "1"
	// +optional
	divisor?: resource.#Quantity @go(Divisor) @protobuf(3,bytes,opt)
}

// Selects a key from a ConfigMap.
// +structType=atomic
#ConfigMapKeySelector: {
	#LocalObjectReference

	// The key to select.
	key: string @go(Key) @protobuf(2,bytes,opt)

	// Specify whether the ConfigMap or its key must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(3,varint,opt)
}

// SecretKeySelector selects a key of a Secret.
// +structType=atomic
#SecretKeySelector: {
	#LocalObjectReference

	// The key of the secret to select from.  Must be a valid secret key.
	key: string @go(Key) @protobuf(2,bytes,opt)

	// Specify whether the Secret or its key must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(3,varint,opt)
}

// EnvFromSource represents the source of a set of ConfigMaps
#EnvFromSource: {
	// An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
	// +optional
	prefix?: string @go(Prefix) @protobuf(1,bytes,opt)

	// The ConfigMap to select from
	// +optional
	configMapRef?: null | #ConfigMapEnvSource @go(ConfigMapRef,*ConfigMapEnvSource) @protobuf(2,bytes,opt)

	// The Secret to select from
	// +optional
	secretRef?: null | #SecretEnvSource @go(SecretRef,*SecretEnvSource) @protobuf(3,bytes,opt)
}

// 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.
#ConfigMapEnvSource: {
	#LocalObjectReference

	// Specify whether the ConfigMap must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(2,varint,opt)
}

// 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.
#SecretEnvSource: {
	#LocalObjectReference

	// Specify whether the Secret must be defined
	// +optional
	optional?: null | bool @go(Optional,*bool) @protobuf(2,varint,opt)
}

// HTTPHeader describes a custom header to be used in HTTP probes
#HTTPHeader: {
	// The header field name
	name: string @go(Name) @protobuf(1,bytes,opt)

	// The header field value
	value: string @go(Value) @protobuf(2,bytes,opt)
}

// HTTPGetAction describes an action based on HTTP Get requests.
#HTTPGetAction: {
	// Path to access on the HTTP server.
	// +optional
	path?: string @go(Path) @protobuf(1,bytes,opt)

	// 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.
	port: intstr.#IntOrString @go(Port) @protobuf(2,bytes,opt)

	// Host name to connect to, defaults to the pod IP. You probably want to set
	// "Host" in httpHeaders instead.
	// +optional
	host?: string @go(Host) @protobuf(3,bytes,opt)

	// Scheme to use for connecting to the host.
	// Defaults to HTTP.
	// +optional
	scheme?: #URIScheme @go(Scheme) @protobuf(4,bytes,opt,casttype=URIScheme)

	// Custom headers to set in the request. HTTP allows repeated headers.
	// +optional
	httpHeaders?: [...#HTTPHeader] @go(HTTPHeaders,[]HTTPHeader) @protobuf(5,bytes,rep)
}

// URIScheme identifies the scheme used for connection to a host for Get actions
// +enum
#URIScheme: string // #enumURIScheme

#enumURIScheme:
	#URISchemeHTTP |
	#URISchemeHTTPS

// URISchemeHTTP means that the scheme used will be http://
#URISchemeHTTP: #URIScheme & "HTTP"

// URISchemeHTTPS means that the scheme used will be https://
#URISchemeHTTPS: #URIScheme & "HTTPS"

// TCPSocketAction describes an action based on opening a socket
#TCPSocketAction: {
	// 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.
	port: intstr.#IntOrString @go(Port) @protobuf(1,bytes,opt)

	// Optional: Host name to connect to, defaults to the pod IP.
	// +optional
	host?: string @go(Host) @protobuf(2,bytes,opt)
}

#GRPCAction: {
	// Port number of the gRPC service. Number must be in the range 1 to 65535.
	port: int32 @go(Port) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	// +default=""
	service?: null | string @go(Service,*string) @protobuf(2,bytes,opt)
}

// ExecAction describes a "run in container" action.
#ExecAction: {
	// 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.
	// +optional
	command?: [...string] @go(Command,[]string) @protobuf(1,bytes,rep)
}

// Probe describes a health check to be performed against a container to determine whether it is
// alive or ready to receive traffic.
#Probe: {
	#ProbeHandler

	// 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
	// +optional
	initialDelaySeconds?: int32 @go(InitialDelaySeconds) @protobuf(2,varint,opt)

	// 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
	// +optional
	timeoutSeconds?: int32 @go(TimeoutSeconds) @protobuf(3,varint,opt)

	// How often (in seconds) to perform the probe.
	// Default to 10 seconds. Minimum value is 1.
	// +optional
	periodSeconds?: int32 @go(PeriodSeconds) @protobuf(4,varint,opt)

	// 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.
	// +optional
	successThreshold?: int32 @go(SuccessThreshold) @protobuf(5,varint,opt)

	// Minimum consecutive failures for the probe to be considered failed after having succeeded.
	// Defaults to 3. Minimum value is 1.
	// +optional
	failureThreshold?: int32 @go(FailureThreshold) @protobuf(6,varint,opt)

	// 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.
	// +optional
	terminationGracePeriodSeconds?: null | int64 @go(TerminationGracePeriodSeconds,*int64) @protobuf(7,varint,opt)
}

// PullPolicy describes a policy for if/when to pull a container image
// +enum
#PullPolicy: string // #enumPullPolicy

#enumPullPolicy:
	#PullAlways |
	#PullNever |
	#PullIfNotPresent

// PullAlways means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
#PullAlways: #PullPolicy & "Always"

// PullNever means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present
#PullNever: #PullPolicy & "Never"

// PullIfNotPresent 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.
#PullIfNotPresent: #PullPolicy & "IfNotPresent"

// PreemptionPolicy describes a policy for if/when to preempt a pod.
// +enum
#PreemptionPolicy: string // #enumPreemptionPolicy

#enumPreemptionPolicy:
	#PreemptLowerPriority |
	#PreemptNever

// PreemptLowerPriority means that pod can preempt other pods with lower priority.
#PreemptLowerPriority: #PreemptionPolicy & "PreemptLowerPriority"

// PreemptNever means that pod never preempts other pods with lower priority.
#PreemptNever: #PreemptionPolicy & "Never"

// TerminationMessagePolicy describes how termination messages are retrieved from a container.
// +enum
#TerminationMessagePolicy: string // #enumTerminationMessagePolicy

#enumTerminationMessagePolicy:
	#TerminationMessageReadFile |
	#TerminationMessageFallbackToLogsOnError

// TerminationMessageReadFile is the default behavior and will set the container status message to
// the contents of the container's terminationMessagePath when the container exits.
#TerminationMessageReadFile: #TerminationMessagePolicy & "File"

// TerminationMessageFallbackToLogsOnError 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.
#TerminationMessageFallbackToLogsOnError: #TerminationMessagePolicy & "FallbackToLogsOnError"

// Capability represent POSIX capabilities type
#Capability: string

// Adds and removes POSIX capabilities from running containers.
#Capabilities: {
	// Added capabilities
	// +optional
	add?: [...#Capability] @go(Add,[]Capability) @protobuf(1,bytes,rep,casttype=Capability)

	// Removed capabilities
	// +optional
	drop?: [...#Capability] @go(Drop,[]Capability) @protobuf(2,bytes,rep,casttype=Capability)
}

// ResourceRequirements describes the compute resource requirements.
#ResourceRequirements: {
	// Limits describes the maximum amount of compute resources allowed.
	// More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
	// +optional
	limits?: #ResourceList @go(Limits) @protobuf(1,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// 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/
	// +optional
	requests?: #ResourceList @go(Requests) @protobuf(2,bytes,rep,casttype=ResourceList,castkey=ResourceName)
}

// TerminationMessagePathDefault means the default path to capture the application termination message running in a container
#TerminationMessagePathDefault: "/dev/termination-log"

// A single application container that you want to run within a pod.
#Container: {
	// Name of the container specified as a DNS_LABEL.
	// Each container in a pod must have a unique name (DNS_LABEL).
	// Cannot be updated.
	name: string @go(Name) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	image?: string @go(Image) @protobuf(2,bytes,opt)

	// 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
	// +optional
	command?: [...string] @go(Command,[]string) @protobuf(3,bytes,rep)

	// 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
	// +optional
	args?: [...string] @go(Args,[]string) @protobuf(4,bytes,rep)

	// 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.
	// +optional
	workingDir?: string @go(WorkingDir) @protobuf(5,bytes,opt)

	// 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.
	// +optional
	// +patchMergeKey=containerPort
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=containerPort
	// +listMapKey=protocol
	ports?: [...#ContainerPort] @go(Ports,[]ContainerPort) @protobuf(6,bytes,rep)

	// 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.
	// +optional
	envFrom?: [...#EnvFromSource] @go(EnvFrom,[]EnvFromSource) @protobuf(19,bytes,rep)

	// List of environment variables to set in the container.
	// Cannot be updated.
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge
	env?: [...#EnvVar] @go(Env,[]EnvVar) @protobuf(7,bytes,rep)

	// Compute Resources required by this container.
	// Cannot be updated.
	// More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
	// +optional
	resources?: #ResourceRequirements @go(Resources) @protobuf(8,bytes,opt)

	// Pod volumes to mount into the container's filesystem.
	// Cannot be updated.
	// +optional
	// +patchMergeKey=mountPath
	// +patchStrategy=merge
	volumeMounts?: [...#VolumeMount] @go(VolumeMounts,[]VolumeMount) @protobuf(9,bytes,rep)

	// volumeDevices is the list of block devices to be used by the container.
	// +patchMergeKey=devicePath
	// +patchStrategy=merge
	// +optional
	volumeDevices?: [...#VolumeDevice] @go(VolumeDevices,[]VolumeDevice) @protobuf(21,bytes,rep)

	// 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
	// +optional
	livenessProbe?: null | #Probe @go(LivenessProbe,*Probe) @protobuf(10,bytes,opt)

	// 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
	// +optional
	readinessProbe?: null | #Probe @go(ReadinessProbe,*Probe) @protobuf(11,bytes,opt)

	// 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
	// +optional
	startupProbe?: null | #Probe @go(StartupProbe,*Probe) @protobuf(22,bytes,opt)

	// Actions that the management system should take in response to container lifecycle events.
	// Cannot be updated.
	// +optional
	lifecycle?: null | #Lifecycle @go(Lifecycle,*Lifecycle) @protobuf(12,bytes,opt)

	// 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.
	// +optional
	terminationMessagePath?: string @go(TerminationMessagePath) @protobuf(13,bytes,opt)

	// 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.
	// +optional
	terminationMessagePolicy?: #TerminationMessagePolicy @go(TerminationMessagePolicy) @protobuf(20,bytes,opt,casttype=TerminationMessagePolicy)

	// 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
	// +optional
	imagePullPolicy?: #PullPolicy @go(ImagePullPolicy) @protobuf(14,bytes,opt,casttype=PullPolicy)

	// 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/
	// +optional
	securityContext?: null | #SecurityContext @go(SecurityContext,*SecurityContext) @protobuf(15,bytes,opt)

	// 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.
	// +optional
	stdin?: bool @go(Stdin) @protobuf(16,varint,opt)

	// 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
	// +optional
	stdinOnce?: bool @go(StdinOnce) @protobuf(17,varint,opt)

	// Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.
	// Default is false.
	// +optional
	tty?: bool @go(TTY) @protobuf(18,varint,opt)
}

// ProbeHandler defines a specific action that should be taken in a probe.
// One and only one of the fields must be specified.
#ProbeHandler: {
	// Exec specifies the action to take.
	// +optional
	exec?: null | #ExecAction @go(Exec,*ExecAction) @protobuf(1,bytes,opt)

	// HTTPGet specifies the http request to perform.
	// +optional
	httpGet?: null | #HTTPGetAction @go(HTTPGet,*HTTPGetAction) @protobuf(2,bytes,opt)

	// TCPSocket specifies an action involving a TCP port.
	// +optional
	tcpSocket?: null | #TCPSocketAction @go(TCPSocket,*TCPSocketAction) @protobuf(3,bytes,opt)

	// GRPC specifies an action involving a GRPC port.
	// This is an alpha field and requires enabling GRPCContainerProbe feature gate.
	// +featureGate=GRPCContainerProbe
	// +optional
	grpc?: null | #GRPCAction @go(GRPC,*GRPCAction) @protobuf(4,bytes,opt)
}

// 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.
#LifecycleHandler: {
	// Exec specifies the action to take.
	// +optional
	exec?: null | #ExecAction @go(Exec,*ExecAction) @protobuf(1,bytes,opt)

	// HTTPGet specifies the http request to perform.
	// +optional
	httpGet?: null | #HTTPGetAction @go(HTTPGet,*HTTPGetAction) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	tcpSocket?: null | #TCPSocketAction @go(TCPSocket,*TCPSocketAction) @protobuf(3,bytes,opt)
}

// 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.
#Lifecycle: {
	// 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
	// +optional
	postStart?: null | #LifecycleHandler @go(PostStart,*LifecycleHandler) @protobuf(1,bytes,opt)

	// 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
	// +optional
	preStop?: null | #LifecycleHandler @go(PreStop,*LifecycleHandler) @protobuf(2,bytes,opt)
}

#ConditionStatus: string // #enumConditionStatus

#enumConditionStatus:
	#ConditionTrue |
	#ConditionFalse |
	#ConditionUnknown

#ConditionTrue:    #ConditionStatus & "True"
#ConditionFalse:   #ConditionStatus & "False"
#ConditionUnknown: #ConditionStatus & "Unknown"

// ContainerStateWaiting is a waiting state of a container.
#ContainerStateWaiting: {
	// (brief) reason the container is not yet running.
	// +optional
	reason?: string @go(Reason) @protobuf(1,bytes,opt)

	// Message regarding why the container is not yet running.
	// +optional
	message?: string @go(Message) @protobuf(2,bytes,opt)
}

// ContainerStateRunning is a running state of a container.
#ContainerStateRunning: {
	// Time at which the container was last (re-)started
	// +optional
	startedAt?: metav1.#Time @go(StartedAt) @protobuf(1,bytes,opt)
}

// ContainerStateTerminated is a terminated state of a container.
#ContainerStateTerminated: {
	// Exit status from the last termination of the container
	exitCode: int32 @go(ExitCode) @protobuf(1,varint,opt)

	// Signal from the last termination of the container
	// +optional
	signal?: int32 @go(Signal) @protobuf(2,varint,opt)

	// (brief) reason from the last termination of the container
	// +optional
	reason?: string @go(Reason) @protobuf(3,bytes,opt)

	// Message regarding the last termination of the container
	// +optional
	message?: string @go(Message) @protobuf(4,bytes,opt)

	// Time at which previous execution of the container started
	// +optional
	startedAt?: metav1.#Time @go(StartedAt) @protobuf(5,bytes,opt)

	// Time at which the container last terminated
	// +optional
	finishedAt?: metav1.#Time @go(FinishedAt) @protobuf(6,bytes,opt)

	// Container's ID in the format 'docker://<container_id>'
	// +optional
	containerID?: string @go(ContainerID) @protobuf(7,bytes,opt)
}

// ContainerState holds a possible state of container.
// Only one of its members may be specified.
// If none of them is specified, the default one is ContainerStateWaiting.
#ContainerState: {
	// Details about a waiting container
	// +optional
	waiting?: null | #ContainerStateWaiting @go(Waiting,*ContainerStateWaiting) @protobuf(1,bytes,opt)

	// Details about a running container
	// +optional
	running?: null | #ContainerStateRunning @go(Running,*ContainerStateRunning) @protobuf(2,bytes,opt)

	// Details about a terminated container
	// +optional
	terminated?: null | #ContainerStateTerminated @go(Terminated,*ContainerStateTerminated) @protobuf(3,bytes,opt)
}

// ContainerStatus contains details for the current status of this container.
#ContainerStatus: {
	// This must be a DNS_LABEL. Each container in a pod must have a unique name.
	// Cannot be updated.
	name: string @go(Name) @protobuf(1,bytes,opt)

	// Details about the container's current condition.
	// +optional
	state?: #ContainerState @go(State) @protobuf(2,bytes,opt)

	// Details about the container's last termination condition.
	// +optional
	lastState?: #ContainerState @go(LastTerminationState) @protobuf(3,bytes,opt)

	// Specifies whether the container has passed its readiness probe.
	ready: bool @go(Ready) @protobuf(4,varint,opt)

	// The number of times the container has been restarted.
	restartCount: int32 @go(RestartCount) @protobuf(5,varint,opt)

	// The image the container is running.
	// More info: https://kubernetes.io/docs/concepts/containers/images.
	image: string @go(Image) @protobuf(6,bytes,opt)

	// ImageID of the container's image.
	imageID: string @go(ImageID) @protobuf(7,bytes,opt)

	// Container's ID in the format 'docker://<container_id>'.
	// +optional
	containerID?: string @go(ContainerID) @protobuf(8,bytes,opt)

	// Specifies whether the container has passed its startup probe.
	// Initialized as false, becomes true after startupProbe is considered successful.
	// Resets to false when the container is restarted, or if kubelet loses state temporarily.
	// Is always true when no startupProbe is defined.
	// +optional
	started?: null | bool @go(Started,*bool) @protobuf(9,varint,opt)
}

// PodPhase is a label for the condition of a pod at the current time.
// +enum
#PodPhase: string // #enumPodPhase

#enumPodPhase:
	#PodPending |
	#PodRunning |
	#PodSucceeded |
	#PodFailed |
	#PodUnknown

// PodPending means the pod has been accepted by the system, but one or more of the containers
// has not been started. This includes time before being bound to a node, as well as time spent
// pulling images onto the host.
#PodPending: #PodPhase & "Pending"

// PodRunning means the pod has been bound to a node and all of the containers have been started.
// At least one container is still running or is in the process of being restarted.
#PodRunning: #PodPhase & "Running"

// PodSucceeded means that all containers in the pod have voluntarily terminated
// with a container exit code of 0, and the system is not going to restart any of these containers.
#PodSucceeded: #PodPhase & "Succeeded"

// PodFailed means that all containers in the pod have terminated, and at least one container has
// terminated in a failure (exited with a non-zero exit code or was stopped by the system).
#PodFailed: #PodPhase & "Failed"

// PodUnknown means that for some reason the state of the pod could not be obtained, typically due
// to an error in communicating with the host of the pod.
// Deprecated: It isn't being set since 2015 (74da3b14b0c0f658b3bb8d2def5094686d0e9095)
#PodUnknown: #PodPhase & "Unknown"

// PodConditionType is a valid value for PodCondition.Type
// +enum
#PodConditionType: string // #enumPodConditionType

#enumPodConditionType:
	#ContainersReady |
	#PodInitialized |
	#PodReady |
	#PodScheduled

// ContainersReady indicates whether all containers in the pod are ready.
#ContainersReady: #PodConditionType & "ContainersReady"

// PodInitialized means that all init containers in the pod have started successfully.
#PodInitialized: #PodConditionType & "Initialized"

// PodReady means the pod is able to service requests and should be added to the
// load balancing pools of all matching services.
#PodReady: #PodConditionType & "Ready"

// PodScheduled represents status of the scheduling process for this pod.
#PodScheduled: #PodConditionType & "PodScheduled"

// PodReasonUnschedulable reason in PodScheduled PodCondition means that the scheduler
// can't schedule the pod right now, for example due to insufficient resources in the cluster.
#PodReasonUnschedulable: "Unschedulable"

// PodCondition contains details for the current condition of this pod.
#PodCondition: {
	// Type is the type of the condition.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions
	type: #PodConditionType @go(Type) @protobuf(1,bytes,opt,casttype=PodConditionType)

	// Status is the status of the condition.
	// Can be True, False, Unknown.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions
	status: #ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=ConditionStatus)

	// Last time we probed the condition.
	// +optional
	lastProbeTime?: metav1.#Time @go(LastProbeTime) @protobuf(3,bytes,opt)

	// Last time the condition transitioned from one status to another.
	// +optional
	lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(4,bytes,opt)

	// Unique, one-word, CamelCase reason for the condition's last transition.
	// +optional
	reason?: string @go(Reason) @protobuf(5,bytes,opt)

	// Human-readable message indicating details about last transition.
	// +optional
	message?: string @go(Message) @protobuf(6,bytes,opt)
}

// RestartPolicy describes how the container should be restarted.
// Only one of the following restart policies may be specified.
// If none of the following policies is specified, the default one
// is RestartPolicyAlways.
// +enum
#RestartPolicy: string // #enumRestartPolicy

#enumRestartPolicy:
	#RestartPolicyAlways |
	#RestartPolicyOnFailure |
	#RestartPolicyNever

#RestartPolicyAlways:    #RestartPolicy & "Always"
#RestartPolicyOnFailure: #RestartPolicy & "OnFailure"
#RestartPolicyNever:     #RestartPolicy & "Never"

// DNSPolicy defines how a pod's DNS will be configured.
// +enum
#DNSPolicy: string // #enumDNSPolicy

#enumDNSPolicy:
	#DNSClusterFirstWithHostNet |
	#DNSClusterFirst |
	#DNSDefault |
	#DNSNone

// DNSClusterFirstWithHostNet 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.
#DNSClusterFirstWithHostNet: #DNSPolicy & "ClusterFirstWithHostNet"

// DNSClusterFirst 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.
#DNSClusterFirst: #DNSPolicy & "ClusterFirst"

// DNSDefault indicates that the pod should use the default (as
// determined by kubelet) DNS settings.
#DNSDefault: #DNSPolicy & "Default"

// DNSNone indicates that the pod should use empty DNS settings. DNS
// parameters such as nameservers and search paths should be defined via
// DNSConfig.
#DNSNone: #DNSPolicy & "None"

// DefaultTerminationGracePeriodSeconds indicates the default duration in
// seconds a pod needs to terminate gracefully.
#DefaultTerminationGracePeriodSeconds: 30

// 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.
// +structType=atomic
#NodeSelector: {
	//Required. A list of node selector terms. The terms are ORed.
	nodeSelectorTerms: [...#NodeSelectorTerm] @go(NodeSelectorTerms,[]NodeSelectorTerm) @protobuf(1,bytes,rep)
}

// 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.
// +structType=atomic
#NodeSelectorTerm: {
	// A list of node selector requirements by node's labels.
	// +optional
	matchExpressions?: [...#NodeSelectorRequirement] @go(MatchExpressions,[]NodeSelectorRequirement) @protobuf(1,bytes,rep)

	// A list of node selector requirements by node's fields.
	// +optional
	matchFields?: [...#NodeSelectorRequirement] @go(MatchFields,[]NodeSelectorRequirement) @protobuf(2,bytes,rep)
}

// A node selector requirement is a selector that contains values, a key, and an operator
// that relates the key and values.
#NodeSelectorRequirement: {
	// The label key that the selector applies to.
	key: string @go(Key) @protobuf(1,bytes,opt)

	// Represents a key's relationship to a set of values.
	// Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
	operator: #NodeSelectorOperator @go(Operator) @protobuf(2,bytes,opt,casttype=NodeSelectorOperator)

	// 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.
	// +optional
	values?: [...string] @go(Values,[]string) @protobuf(3,bytes,rep)
}

// A node selector operator is the set of operators that can be used in
// a node selector requirement.
// +enum
#NodeSelectorOperator: string // #enumNodeSelectorOperator

#enumNodeSelectorOperator:
	#NodeSelectorOpIn |
	#NodeSelectorOpNotIn |
	#NodeSelectorOpExists |
	#NodeSelectorOpDoesNotExist |
	#NodeSelectorOpGt |
	#NodeSelectorOpLt

#NodeSelectorOpIn:           #NodeSelectorOperator & "In"
#NodeSelectorOpNotIn:        #NodeSelectorOperator & "NotIn"
#NodeSelectorOpExists:       #NodeSelectorOperator & "Exists"
#NodeSelectorOpDoesNotExist: #NodeSelectorOperator & "DoesNotExist"
#NodeSelectorOpGt:           #NodeSelectorOperator & "Gt"
#NodeSelectorOpLt:           #NodeSelectorOperator & "Lt"

// 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.
// +structType=atomic
#TopologySelectorTerm: {
	// A list of topology selector requirements by labels.
	// +optional
	matchLabelExpressions?: [...#TopologySelectorLabelRequirement] @go(MatchLabelExpressions,[]TopologySelectorLabelRequirement) @protobuf(1,bytes,rep)
}

// A topology selector requirement is a selector that matches given label.
// This is an alpha feature and may change in the future.
#TopologySelectorLabelRequirement: {
	// The label key that the selector applies to.
	key: string @go(Key) @protobuf(1,bytes,opt)

	// An array of string values. One value must match the label to be selected.
	// Each entry in Values is ORed.
	values: [...string] @go(Values,[]string) @protobuf(2,bytes,rep)
}

// Affinity is a group of affinity scheduling rules.
#Affinity: {
	// Describes node affinity scheduling rules for the pod.
	// +optional
	nodeAffinity?: null | #NodeAffinity @go(NodeAffinity,*NodeAffinity) @protobuf(1,bytes,opt)

	// Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).
	// +optional
	podAffinity?: null | #PodAffinity @go(PodAffinity,*PodAffinity) @protobuf(2,bytes,opt)

	// Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).
	// +optional
	podAntiAffinity?: null | #PodAntiAffinity @go(PodAntiAffinity,*PodAntiAffinity) @protobuf(3,bytes,opt)
}

// Pod affinity is a group of inter pod affinity scheduling rules.
#PodAffinity: {
	// 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.
	// +optional
	requiredDuringSchedulingIgnoredDuringExecution?: [...#PodAffinityTerm] @go(RequiredDuringSchedulingIgnoredDuringExecution,[]PodAffinityTerm) @protobuf(1,bytes,rep)

	// 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.
	// +optional
	preferredDuringSchedulingIgnoredDuringExecution?: [...#WeightedPodAffinityTerm] @go(PreferredDuringSchedulingIgnoredDuringExecution,[]WeightedPodAffinityTerm) @protobuf(2,bytes,rep)
}

// Pod anti affinity is a group of inter pod anti affinity scheduling rules.
#PodAntiAffinity: {
	// 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.
	// +optional
	requiredDuringSchedulingIgnoredDuringExecution?: [...#PodAffinityTerm] @go(RequiredDuringSchedulingIgnoredDuringExecution,[]PodAffinityTerm) @protobuf(1,bytes,rep)

	// 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.
	// +optional
	preferredDuringSchedulingIgnoredDuringExecution?: [...#WeightedPodAffinityTerm] @go(PreferredDuringSchedulingIgnoredDuringExecution,[]WeightedPodAffinityTerm) @protobuf(2,bytes,rep)
}

// The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)
#WeightedPodAffinityTerm: {
	// weight associated with matching the corresponding podAffinityTerm,
	// in the range 1-100.
	weight: int32 @go(Weight) @protobuf(1,varint,opt)

	// Required. A pod affinity term, associated with the corresponding weight.
	podAffinityTerm: #PodAffinityTerm @go(PodAffinityTerm) @protobuf(2,bytes,opt)
}

// 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 <topologyKey> matches that of any node on which
// a pod of the set of pods is running
#PodAffinityTerm: {
	// A label query over a set of resources, in this case pods.
	// +optional
	labelSelector?: null | metav1.#LabelSelector @go(LabelSelector,*metav1.LabelSelector) @protobuf(1,bytes,opt)

	// 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"
	// +optional
	namespaces?: [...string] @go(Namespaces,[]string) @protobuf(2,bytes,rep)

	// 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.
	topologyKey: string @go(TopologyKey) @protobuf(3,bytes,opt)

	// 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.
	// +optional
	namespaceSelector?: null | metav1.#LabelSelector @go(NamespaceSelector,*metav1.LabelSelector) @protobuf(4,bytes,opt)
}

// Node affinity is a group of node affinity scheduling rules.
#NodeAffinity: {
	// 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.
	// +optional
	requiredDuringSchedulingIgnoredDuringExecution?: null | #NodeSelector @go(RequiredDuringSchedulingIgnoredDuringExecution,*NodeSelector) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	preferredDuringSchedulingIgnoredDuringExecution?: [...#PreferredSchedulingTerm] @go(PreferredDuringSchedulingIgnoredDuringExecution,[]PreferredSchedulingTerm) @protobuf(2,bytes,rep)
}

// 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).
#PreferredSchedulingTerm: {
	// Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.
	weight: int32 @go(Weight) @protobuf(1,varint,opt)

	// A node selector term, associated with the corresponding weight.
	preference: #NodeSelectorTerm @go(Preference) @protobuf(2,bytes,opt)
}

// The node this Taint is attached to has the "effect" on
// any pod that does not tolerate the Taint.
#Taint: {
	// Required. The taint key to be applied to a node.
	key: string @go(Key) @protobuf(1,bytes,opt)

	// The taint value corresponding to the taint key.
	// +optional
	value?: string @go(Value) @protobuf(2,bytes,opt)

	// Required. The effect of the taint on pods
	// that do not tolerate the taint.
	// Valid effects are NoSchedule, PreferNoSchedule and NoExecute.
	effect: #TaintEffect @go(Effect) @protobuf(3,bytes,opt,casttype=TaintEffect)

	// TimeAdded represents the time at which the taint was added.
	// It is only written for NoExecute taints.
	// +optional
	timeAdded?: null | metav1.#Time @go(TimeAdded,*metav1.Time) @protobuf(4,bytes,opt)
}

// +enum
#TaintEffect: string // #enumTaintEffect

#enumTaintEffect:
	#TaintEffectNoSchedule |
	#TaintEffectPreferNoSchedule |
	#TaintEffectNoExecute

// 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.
#TaintEffectNoSchedule: #TaintEffect & "NoSchedule"

// 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.
#TaintEffectPreferNoSchedule: #TaintEffect & "PreferNoSchedule"

// Evict any already-running pods that do not tolerate the taint.
// Currently enforced by NodeController.
#TaintEffectNoExecute: #TaintEffect & "NoExecute"

// The pod this Toleration is attached to tolerates any taint that matches
// the triple <key,value,effect> using the matching operator <operator>.
#Toleration: {
	// 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.
	// +optional
	key?: string @go(Key) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	operator?: #TolerationOperator @go(Operator) @protobuf(2,bytes,opt,casttype=TolerationOperator)

	// Value is the taint value the toleration matches to.
	// If the operator is Exists, the value should be empty, otherwise just a regular string.
	// +optional
	value?: string @go(Value) @protobuf(3,bytes,opt)

	// Effect indicates the taint effect to match. Empty means match all taint effects.
	// When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
	// +optional
	effect?: #TaintEffect @go(Effect) @protobuf(4,bytes,opt,casttype=TaintEffect)

	// 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.
	// +optional
	tolerationSeconds?: null | int64 @go(TolerationSeconds,*int64) @protobuf(5,varint,opt)
}

// A toleration operator is the set of operators that can be used in a toleration.
// +enum
#TolerationOperator: string // #enumTolerationOperator

#enumTolerationOperator:
	#TolerationOpExists |
	#TolerationOpEqual

#TolerationOpExists: #TolerationOperator & "Exists"
#TolerationOpEqual:  #TolerationOperator & "Equal"

// PodReadinessGate contains the reference to a pod condition
#PodReadinessGate: {
	// ConditionType refers to a condition in the pod's condition list with matching type.
	conditionType: #PodConditionType @go(ConditionType) @protobuf(1,bytes,opt,casttype=PodConditionType)
}

// PodSpec is a description of a pod.
#PodSpec: {
	// List of volumes that can be mounted by containers belonging to the pod.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge,retainKeys
	volumes?: [...#Volume] @go(Volumes,[]Volume) @protobuf(1,bytes,rep)

	// 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/
	// +patchMergeKey=name
	// +patchStrategy=merge
	initContainers?: [...#Container] @go(InitContainers,[]Container) @protobuf(20,bytes,rep)

	// 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.
	// +patchMergeKey=name
	// +patchStrategy=merge
	containers: [...#Container] @go(Containers,[]Container) @protobuf(2,bytes,rep)

	// 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.
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge
	ephemeralContainers?: [...#EphemeralContainer] @go(EphemeralContainers,[]EphemeralContainer) @protobuf(34,bytes,rep)

	// 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
	// +optional
	restartPolicy?: #RestartPolicy @go(RestartPolicy) @protobuf(3,bytes,opt,casttype=RestartPolicy)

	// 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.
	// +optional
	terminationGracePeriodSeconds?: null | int64 @go(TerminationGracePeriodSeconds,*int64) @protobuf(4,varint,opt)

	// 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.
	// +optional
	activeDeadlineSeconds?: null | int64 @go(ActiveDeadlineSeconds,*int64) @protobuf(5,varint,opt)

	// 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'.
	// +optional
	dnsPolicy?: #DNSPolicy @go(DNSPolicy) @protobuf(6,bytes,opt,casttype=DNSPolicy)

	// 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/
	// +optional
	// +mapType=atomic
	nodeSelector?: {[string]: string} @go(NodeSelector,map[string]string) @protobuf(7,bytes,rep)

	// 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/
	// +optional
	serviceAccountName?: string @go(ServiceAccountName) @protobuf(8,bytes,opt)

	// DeprecatedServiceAccount is a depreciated alias for ServiceAccountName.
	// Deprecated: Use serviceAccountName instead.
	// +k8s:conversion-gen=false
	// +optional
	serviceAccount?: string @go(DeprecatedServiceAccount) @protobuf(9,bytes,opt)

	// AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.
	// +optional
	automountServiceAccountToken?: null | bool @go(AutomountServiceAccountToken,*bool) @protobuf(21,varint,opt)

	// 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.
	// +optional
	nodeName?: string @go(NodeName) @protobuf(10,bytes,opt)

	// 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.
	// +k8s:conversion-gen=false
	// +optional
	hostNetwork?: bool @go(HostNetwork) @protobuf(11,varint,opt)

	// Use the host's pid namespace.
	// Optional: Default to false.
	// +k8s:conversion-gen=false
	// +optional
	hostPID?: bool @go(HostPID) @protobuf(12,varint,opt)

	// Use the host's ipc namespace.
	// Optional: Default to false.
	// +k8s:conversion-gen=false
	// +optional
	hostIPC?: bool @go(HostIPC) @protobuf(13,varint,opt)

	// 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.
	// +k8s:conversion-gen=false
	// +optional
	shareProcessNamespace?: null | bool @go(ShareProcessNamespace,*bool) @protobuf(27,varint,opt)

	// SecurityContext holds pod-level security attributes and common container settings.
	// Optional: Defaults to empty.  See type description for default values of each field.
	// +optional
	securityContext?: null | #PodSecurityContext @go(SecurityContext,*PodSecurityContext) @protobuf(14,bytes,opt)

	// 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
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge
	imagePullSecrets?: [...#LocalObjectReference] @go(ImagePullSecrets,[]LocalObjectReference) @protobuf(15,bytes,rep)

	// Specifies the hostname of the Pod
	// If not specified, the pod's hostname will be set to a system-defined value.
	// +optional
	hostname?: string @go(Hostname) @protobuf(16,bytes,opt)

	// If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".
	// If not specified, the pod will not have a domainname at all.
	// +optional
	subdomain?: string @go(Subdomain) @protobuf(17,bytes,opt)

	// If specified, the pod's scheduling constraints
	// +optional
	affinity?: null | #Affinity @go(Affinity,*Affinity) @protobuf(18,bytes,opt)

	// If specified, the pod will be dispatched by specified scheduler.
	// If not specified, the pod will be dispatched by default scheduler.
	// +optional
	schedulerName?: string @go(SchedulerName) @protobuf(19,bytes,opt)

	// If specified, the pod's tolerations.
	// +optional
	tolerations?: [...#Toleration] @go(Tolerations,[]Toleration) @protobuf(22,bytes,opt)

	// 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.
	// +optional
	// +patchMergeKey=ip
	// +patchStrategy=merge
	hostAliases?: [...#HostAlias] @go(HostAliases,[]HostAlias) @protobuf(23,bytes,rep)

	// 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.
	// +optional
	priorityClassName?: string @go(PriorityClassName) @protobuf(24,bytes,opt)

	// 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.
	// +optional
	priority?: null | int32 @go(Priority,*int32) @protobuf(25,bytes,opt)

	// Specifies the DNS parameters of a pod.
	// Parameters specified here will be merged to the generated DNS
	// configuration based on DNSPolicy.
	// +optional
	dnsConfig?: null | #PodDNSConfig @go(DNSConfig,*PodDNSConfig) @protobuf(26,bytes,opt)

	// 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
	// +optional
	readinessGates?: [...#PodReadinessGate] @go(ReadinessGates,[]PodReadinessGate) @protobuf(28,bytes,opt)

	// 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.
	// +optional
	runtimeClassName?: null | string @go(RuntimeClassName,*string) @protobuf(29,bytes,opt)

	// EnableServiceLinks indicates whether information about services should be injected into pod's
	// environment variables, matching the syntax of Docker links.
	// Optional: Defaults to true.
	// +optional
	enableServiceLinks?: null | bool @go(EnableServiceLinks,*bool) @protobuf(30,varint,opt)

	// 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.
	// +optional
	preemptionPolicy?: null | #PreemptionPolicy @go(PreemptionPolicy,*PreemptionPolicy) @protobuf(31,bytes,opt)

	// 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.
	// +optional
	overhead?: #ResourceList @go(Overhead) @protobuf(32,bytes,opt)

	// 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.
	// +optional
	// +patchMergeKey=topologyKey
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=topologyKey
	// +listMapKey=whenUnsatisfiable
	topologySpreadConstraints?: [...#TopologySpreadConstraint] @go(TopologySpreadConstraints,[]TopologySpreadConstraint) @protobuf(33,bytes,opt)

	// 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.
	// +optional
	setHostnameAsFQDN?: null | bool @go(SetHostnameAsFQDN,*bool) @protobuf(35,varint,opt)

	// 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
	// +optional
	// This is an alpha field and requires the IdentifyPodOS feature
	os?: null | #PodOS @go(OS,*PodOS) @protobuf(36,bytes,opt)
}

// OSName is the set of OS'es that can be used in OS.
#OSName: string // #enumOSName

#enumOSName:
	#Linux |
	#Windows

#Linux:   #OSName & "linux"
#Windows: #OSName & "windows"

// PodOS defines the OS parameters of a pod.
#PodOS: {
	// 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
	name: #OSName @go(Name) @protobuf(1,bytes,opt)
}

// +enum
#UnsatisfiableConstraintAction: string // #enumUnsatisfiableConstraintAction

#enumUnsatisfiableConstraintAction:
	#DoNotSchedule |
	#ScheduleAnyway

// DoNotSchedule instructs the scheduler not to schedule the pod
// when constraints are not satisfied.
#DoNotSchedule: #UnsatisfiableConstraintAction & "DoNotSchedule"

// ScheduleAnyway instructs the scheduler to schedule the pod
// even if constraints are not satisfied.
#ScheduleAnyway: #UnsatisfiableConstraintAction & "ScheduleAnyway"

// TopologySpreadConstraint specifies how to spread matching pods among the given topology.
#TopologySpreadConstraint: {
	// 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.
	maxSkew: int32 @go(MaxSkew) @protobuf(1,varint,opt)

	// 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.
	topologyKey: string @go(TopologyKey) @protobuf(2,bytes,opt)

	// 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.
	whenUnsatisfiable: #UnsatisfiableConstraintAction @go(WhenUnsatisfiable) @protobuf(3,bytes,opt,casttype=UnsatisfiableConstraintAction)

	// 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.
	// +optional
	labelSelector?: null | metav1.#LabelSelector @go(LabelSelector,*metav1.LabelSelector) @protobuf(4,bytes,opt)
}

// The default value for enableServiceLinks attribute.
#DefaultEnableServiceLinks: true

// HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the
// pod's hosts file.
#HostAlias: {
	// IP address of the host file entry.
	ip?: string @go(IP) @protobuf(1,bytes,opt)

	// Hostnames for the above IP address.
	hostnames?: [...string] @go(Hostnames,[]string) @protobuf(2,bytes,rep)
}

// PodFSGroupChangePolicy holds policies that will be used for applying fsGroup to a volume
// when volume is mounted.
// +enum
#PodFSGroupChangePolicy: string // #enumPodFSGroupChangePolicy

#enumPodFSGroupChangePolicy:
	#FSGroupChangeOnRootMismatch |
	#FSGroupChangeAlways

// FSGroupChangeOnRootMismatch indicates that volume's ownership and permissions will be changed
// only when permission and ownership of root directory does not match with expected
// permissions on the volume. This can help shorten the time it takes to change
// ownership and permissions of a volume.
#FSGroupChangeOnRootMismatch: #PodFSGroupChangePolicy & "OnRootMismatch"

// FSGroupChangeAlways indicates that volume's ownership and permissions
// should always be changed whenever volume is mounted inside a Pod. This the default
// behavior.
#FSGroupChangeAlways: #PodFSGroupChangePolicy & "Always"

// 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.
#PodSecurityContext: {
	// 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.
	// +optional
	seLinuxOptions?: null | #SELinuxOptions @go(SELinuxOptions,*SELinuxOptions) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	windowsOptions?: null | #WindowsSecurityContextOptions @go(WindowsOptions,*WindowsSecurityContextOptions) @protobuf(8,bytes,opt)

	// 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.
	// +optional
	runAsUser?: null | int64 @go(RunAsUser,*int64) @protobuf(2,varint,opt)

	// 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.
	// +optional
	runAsGroup?: null | int64 @go(RunAsGroup,*int64) @protobuf(6,varint,opt)

	// 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.
	// +optional
	runAsNonRoot?: null | bool @go(RunAsNonRoot,*bool) @protobuf(3,varint,opt)

	// 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.
	// +optional
	supplementalGroups?: [...int64] @go(SupplementalGroups,[]int64) @protobuf(4,varint,rep)

	// 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.
	// +optional
	fsGroup?: null | int64 @go(FSGroup,*int64) @protobuf(5,varint,opt)

	// 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.
	// +optional
	sysctls?: [...#Sysctl] @go(Sysctls,[]Sysctl) @protobuf(7,bytes,rep)

	// 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.
	// +optional
	fsGroupChangePolicy?: null | #PodFSGroupChangePolicy @go(FSGroupChangePolicy,*PodFSGroupChangePolicy) @protobuf(9,bytes,opt)

	// The seccomp options to use by the containers in this pod.
	// Note that this field cannot be set when spec.os.name is windows.
	// +optional
	seccompProfile?: null | #SeccompProfile @go(SeccompProfile,*SeccompProfile) @protobuf(10,bytes,opt)
}

// SeccompProfile defines a pod/container's seccomp profile settings.
// Only one profile source may be set.
// +union
#SeccompProfile: {
	// 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.
	// +unionDiscriminator
	type: #SeccompProfileType @go(Type) @protobuf(1,bytes,opt,casttype=SeccompProfileType)

	// 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".
	// +optional
	localhostProfile?: null | string @go(LocalhostProfile,*string) @protobuf(2,bytes,opt)
}

// SeccompProfileType defines the supported seccomp profile types.
// +enum
#SeccompProfileType: string // #enumSeccompProfileType

#enumSeccompProfileType:
	#SeccompProfileTypeUnconfined |
	#SeccompProfileTypeRuntimeDefault |
	#SeccompProfileTypeLocalhost

// SeccompProfileTypeUnconfined indicates no seccomp profile is applied (A.K.A. unconfined).
#SeccompProfileTypeUnconfined: #SeccompProfileType & "Unconfined"

// SeccompProfileTypeRuntimeDefault represents the default container runtime seccomp profile.
#SeccompProfileTypeRuntimeDefault: #SeccompProfileType & "RuntimeDefault"

// SeccompProfileTypeLocalhost indicates a profile defined in a file on the node should be used.
// The file's location relative to <kubelet-root-dir>/seccomp.
#SeccompProfileTypeLocalhost: #SeccompProfileType & "Localhost"

// PodQOSClass defines the supported qos classes of Pods.
// +enum
#PodQOSClass: string // #enumPodQOSClass

#enumPodQOSClass:
	#PodQOSGuaranteed |
	#PodQOSBurstable |
	#PodQOSBestEffort

// PodQOSGuaranteed is the Guaranteed qos class.
#PodQOSGuaranteed: #PodQOSClass & "Guaranteed"

// PodQOSBurstable is the Burstable qos class.
#PodQOSBurstable: #PodQOSClass & "Burstable"

// PodQOSBestEffort is the BestEffort qos class.
#PodQOSBestEffort: #PodQOSClass & "BestEffort"

// PodDNSConfig defines the DNS parameters of a pod in addition to
// those generated from DNSPolicy.
#PodDNSConfig: {
	// A list of DNS name server IP addresses.
	// This will be appended to the base nameservers generated from DNSPolicy.
	// Duplicated nameservers will be removed.
	// +optional
	nameservers?: [...string] @go(Nameservers,[]string) @protobuf(1,bytes,rep)

	// 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.
	// +optional
	searches?: [...string] @go(Searches,[]string) @protobuf(2,bytes,rep)

	// 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.
	// +optional
	options?: [...#PodDNSConfigOption] @go(Options,[]PodDNSConfigOption) @protobuf(3,bytes,rep)
}

// PodDNSConfigOption defines DNS resolver options of a pod.
#PodDNSConfigOption: {
	// Required.
	name?: string @go(Name) @protobuf(1,bytes,opt)

	// +optional
	value?: null | string @go(Value,*string) @protobuf(2,bytes,opt)
}

// IP address information for entries in the (plural) PodIPs field.
// Each entry includes:
//    IP: An IP address allocated to the pod. Routable at least within the cluster.
#PodIP: {
	// ip is an IP address (IPv4 or IPv6) assigned to the pod
	ip?: string @go(IP) @protobuf(1,bytes,opt)
}

// EphemeralContainerCommon is a copy of all fields in Container to be inlined in
// EphemeralContainer. This separate type allows easy conversion from EphemeralContainer
// to Container and allows separate documentation for the fields of EphemeralContainer.
// When a new field is added to Container it must be added here as well.
#EphemeralContainerCommon: {
	// Name of the ephemeral container specified as a DNS_LABEL.
	// This name must be unique among all containers, init containers and ephemeral containers.
	name: string @go(Name) @protobuf(1,bytes,opt)

	// Docker image name.
	// More info: https://kubernetes.io/docs/concepts/containers/images
	image?: string @go(Image) @protobuf(2,bytes,opt)

	// 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
	// +optional
	command?: [...string] @go(Command,[]string) @protobuf(3,bytes,rep)

	// 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
	// +optional
	args?: [...string] @go(Args,[]string) @protobuf(4,bytes,rep)

	// 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.
	// +optional
	workingDir?: string @go(WorkingDir) @protobuf(5,bytes,opt)

	// Ports are not allowed for ephemeral containers.
	// +optional
	// +patchMergeKey=containerPort
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=containerPort
	// +listMapKey=protocol
	ports?: [...#ContainerPort] @go(Ports,[]ContainerPort) @protobuf(6,bytes,rep)

	// 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.
	// +optional
	envFrom?: [...#EnvFromSource] @go(EnvFrom,[]EnvFromSource) @protobuf(19,bytes,rep)

	// List of environment variables to set in the container.
	// Cannot be updated.
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge
	env?: [...#EnvVar] @go(Env,[]EnvVar) @protobuf(7,bytes,rep)

	// Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources
	// already allocated to the pod.
	// +optional
	resources?: #ResourceRequirements @go(Resources) @protobuf(8,bytes,opt)

	// Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers.
	// Cannot be updated.
	// +optional
	// +patchMergeKey=mountPath
	// +patchStrategy=merge
	volumeMounts?: [...#VolumeMount] @go(VolumeMounts,[]VolumeMount) @protobuf(9,bytes,rep)

	// volumeDevices is the list of block devices to be used by the container.
	// +patchMergeKey=devicePath
	// +patchStrategy=merge
	// +optional
	volumeDevices?: [...#VolumeDevice] @go(VolumeDevices,[]VolumeDevice) @protobuf(21,bytes,rep)

	// Probes are not allowed for ephemeral containers.
	// +optional
	livenessProbe?: null | #Probe @go(LivenessProbe,*Probe) @protobuf(10,bytes,opt)

	// Probes are not allowed for ephemeral containers.
	// +optional
	readinessProbe?: null | #Probe @go(ReadinessProbe,*Probe) @protobuf(11,bytes,opt)

	// Probes are not allowed for ephemeral containers.
	// +optional
	startupProbe?: null | #Probe @go(StartupProbe,*Probe) @protobuf(22,bytes,opt)

	// Lifecycle is not allowed for ephemeral containers.
	// +optional
	lifecycle?: null | #Lifecycle @go(Lifecycle,*Lifecycle) @protobuf(12,bytes,opt)

	// 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.
	// +optional
	terminationMessagePath?: string @go(TerminationMessagePath) @protobuf(13,bytes,opt)

	// 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.
	// +optional
	terminationMessagePolicy?: #TerminationMessagePolicy @go(TerminationMessagePolicy) @protobuf(20,bytes,opt,casttype=TerminationMessagePolicy)

	// 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
	// +optional
	imagePullPolicy?: #PullPolicy @go(ImagePullPolicy) @protobuf(14,bytes,opt,casttype=PullPolicy)

	// 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.
	// +optional
	securityContext?: null | #SecurityContext @go(SecurityContext,*SecurityContext) @protobuf(15,bytes,opt)

	// 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.
	// +optional
	stdin?: bool @go(Stdin) @protobuf(16,varint,opt)

	// 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
	// +optional
	stdinOnce?: bool @go(StdinOnce) @protobuf(17,varint,opt)

	// Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.
	// Default is false.
	// +optional
	tty?: bool @go(TTY) @protobuf(18,varint,opt)
}

// 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.
#EphemeralContainer: {
	#EphemeralContainerCommon

	// 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.
	// +optional
	targetContainerName?: string @go(TargetContainerName) @protobuf(2,bytes,opt)
}

// PodStatus represents information about the status of a pod. Status may trail the actual
// state of a system, especially if the node that hosts the pod cannot contact the control
// plane.
#PodStatus: {
	// The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle.
	// The conditions array, the reason and message fields, and the individual container status
	// arrays contain more detail about the pod's status.
	// There are five possible phase values:
	//
	// Pending: The pod has been accepted by the Kubernetes system, but one or more of the
	// container images has not been created. This includes time before being scheduled as
	// well as time spent downloading images over the network, which could take a while.
	// Running: The pod has been bound to a node, and all of the containers have been created.
	// At least one container is still running, or is in the process of starting or restarting.
	// Succeeded: All containers in the pod have terminated in success, and will not be restarted.
	// Failed: All containers in the pod have terminated, and at least one container has
	// terminated in failure. The container either exited with non-zero status or was terminated
	// by the system.
	// Unknown: For some reason the state of the pod could not be obtained, typically due to an
	// error in communicating with the host of the pod.
	//
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase
	// +optional
	phase?: #PodPhase @go(Phase) @protobuf(1,bytes,opt,casttype=PodPhase)

	// Current service state of pod.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	conditions?: [...#PodCondition] @go(Conditions,[]PodCondition) @protobuf(2,bytes,rep)

	// A human readable message indicating details about why the pod is in this condition.
	// +optional
	message?: string @go(Message) @protobuf(3,bytes,opt)

	// A brief CamelCase message indicating details about why the pod is in this state.
	// e.g. 'Evicted'
	// +optional
	reason?: string @go(Reason) @protobuf(4,bytes,opt)

	// nominatedNodeName is set only when this pod preempts other pods on the node, but it cannot be
	// scheduled right away as preemption victims receive their graceful termination periods.
	// This field does not guarantee that the pod will be scheduled on this node. Scheduler may decide
	// to place the pod elsewhere if other nodes become available sooner. Scheduler may also decide to
	// give the resources on this node to a higher priority pod that is created after preemption.
	// As a result, this field may be different than PodSpec.nodeName when the pod is
	// scheduled.
	// +optional
	nominatedNodeName?: string @go(NominatedNodeName) @protobuf(11,bytes,opt)

	// IP address of the host to which the pod is assigned. Empty if not yet scheduled.
	// +optional
	hostIP?: string @go(HostIP) @protobuf(5,bytes,opt)

	// IP address allocated to the pod. Routable at least within the cluster.
	// Empty if not yet allocated.
	// +optional
	podIP?: string @go(PodIP) @protobuf(6,bytes,opt)

	// podIPs holds the IP addresses allocated to the pod. If this field is specified, the 0th entry must
	// match the podIP field. Pods may be allocated at most 1 value for each of IPv4 and IPv6. This list
	// is empty if no IPs have been allocated yet.
	// +optional
	// +patchStrategy=merge
	// +patchMergeKey=ip
	podIPs?: [...#PodIP] @go(PodIPs,[]PodIP) @protobuf(12,bytes,rep)

	// RFC 3339 date and time at which the object was acknowledged by the Kubelet.
	// This is before the Kubelet pulled the container image(s) for the pod.
	// +optional
	startTime?: null | metav1.#Time @go(StartTime,*metav1.Time) @protobuf(7,bytes,opt)

	// The list has one entry per init container in the manifest. The most recent successful
	// init container will have ready = true, the most recently started container will have
	// startTime set.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status
	initContainerStatuses?: [...#ContainerStatus] @go(InitContainerStatuses,[]ContainerStatus) @protobuf(10,bytes,rep)

	// The list has one entry per container in the manifest. Each entry is currently the output
	// of `docker inspect`.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status
	// +optional
	containerStatuses?: [...#ContainerStatus] @go(ContainerStatuses,[]ContainerStatus) @protobuf(8,bytes,rep)

	// The Quality of Service (QOS) classification assigned to the pod based on resource requirements
	// See PodQOSClass type for available QOS classes
	// More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md
	// +optional
	qosClass?: #PodQOSClass @go(QOSClass) @protobuf(9,bytes,rep)

	// Status for any ephemeral containers that have run in this pod.
	// This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.
	// +optional
	ephemeralContainerStatuses?: [...#ContainerStatus] @go(EphemeralContainerStatuses,[]ContainerStatus) @protobuf(13,bytes,rep)
}

// PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded
#PodStatusResult: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Most recently observed status of the pod.
	// This data may not be up to date.
	// Populated by the system.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #PodStatus @go(Status) @protobuf(2,bytes,opt)
}

// Pod is a collection of containers that can run on a host. This resource is created
// by clients and scheduled onto hosts.
#Pod: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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
	// +optional
	spec?: #PodSpec @go(Spec) @protobuf(2,bytes,opt)

	// Most recently observed status of the pod.
	// This data may not be up to date.
	// Populated by the system.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #PodStatus @go(Status) @protobuf(3,bytes,opt)
}

// PodList is a list of Pods.
#PodList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of pods.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
	items: [...#Pod] @go(Items,[]Pod) @protobuf(2,bytes,rep)
}

// PodTemplateSpec describes the data a pod should have when created from a template
#PodTemplateSpec: {
	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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
	// +optional
	spec?: #PodSpec @go(Spec) @protobuf(2,bytes,opt)
}

// PodTemplate describes a template for creating copies of a predefined pod.
#PodTemplate: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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
	// +optional
	template?: #PodTemplateSpec @go(Template) @protobuf(2,bytes,opt)
}

// PodTemplateList is a list of PodTemplates.
#PodTemplateList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of pod templates
	items: [...#PodTemplate] @go(Items,[]PodTemplate) @protobuf(2,bytes,rep)
}

// ReplicationControllerSpec is the specification of a replication controller.
#ReplicationControllerSpec: {
	// 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
	// +optional
	replicas?: null | int32 @go(Replicas,*int32) @protobuf(1,varint,opt)

	// 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)
	// +optional
	minReadySeconds?: int32 @go(MinReadySeconds) @protobuf(4,varint,opt)

	// 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
	// +optional
	// +mapType=atomic
	selector?: {[string]: string} @go(Selector,map[string]string) @protobuf(2,bytes,rep)

	// 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
	// +optional
	template?: null | #PodTemplateSpec @go(Template,*PodTemplateSpec) @protobuf(3,bytes,opt)
}

// ReplicationControllerStatus represents the current status of a replication
// controller.
#ReplicationControllerStatus: {
	// Replicas is the most recently oberved number of replicas.
	// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller
	replicas: int32 @go(Replicas) @protobuf(1,varint,opt)

	// The number of pods that have labels matching the labels of the pod template of the replication controller.
	// +optional
	fullyLabeledReplicas?: int32 @go(FullyLabeledReplicas) @protobuf(2,varint,opt)

	// The number of ready replicas for this replication controller.
	// +optional
	readyReplicas?: int32 @go(ReadyReplicas) @protobuf(4,varint,opt)

	// The number of available replicas (ready for at least minReadySeconds) for this replication controller.
	// +optional
	availableReplicas?: int32 @go(AvailableReplicas) @protobuf(5,varint,opt)

	// ObservedGeneration reflects the generation of the most recently observed replication controller.
	// +optional
	observedGeneration?: int64 @go(ObservedGeneration) @protobuf(3,varint,opt)

	// Represents the latest available observations of a replication controller's current state.
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	conditions?: [...#ReplicationControllerCondition] @go(Conditions,[]ReplicationControllerCondition) @protobuf(6,bytes,rep)
}

#ReplicationControllerConditionType: string // #enumReplicationControllerConditionType

#enumReplicationControllerConditionType:
	#ReplicationControllerReplicaFailure

// ReplicationControllerReplicaFailure is added in a replication controller when one of its pods
// fails to be created due to insufficient quota, limit ranges, pod security policy, node selectors,
// etc. or deleted due to kubelet being down or finalizers are failing.
#ReplicationControllerReplicaFailure: #ReplicationControllerConditionType & "ReplicaFailure"

// ReplicationControllerCondition describes the state of a replication controller at a certain point.
#ReplicationControllerCondition: {
	// Type of replication controller condition.
	type: #ReplicationControllerConditionType @go(Type) @protobuf(1,bytes,opt,casttype=ReplicationControllerConditionType)

	// Status of the condition, one of True, False, Unknown.
	status: #ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=ConditionStatus)

	// The last time the condition transitioned from one status to another.
	// +optional
	lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(3,bytes,opt)

	// The reason for the condition's last transition.
	// +optional
	reason?: string @go(Reason) @protobuf(4,bytes,opt)

	// A human readable message indicating details about the transition.
	// +optional
	message?: string @go(Message) @protobuf(5,bytes,opt)
}

// ReplicationController represents the configuration of a replication controller.
#ReplicationController: {
	metav1.#TypeMeta

	// 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
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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
	// +optional
	spec?: #ReplicationControllerSpec @go(Spec) @protobuf(2,bytes,opt)

	// Status is the most recently observed status of the replication controller.
	// This data may be out of date by some window of time.
	// Populated by the system.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #ReplicationControllerStatus @go(Status) @protobuf(3,bytes,opt)
}

// ReplicationControllerList is a collection of replication controllers.
#ReplicationControllerList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of replication controllers.
	// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
	items: [...#ReplicationController] @go(Items,[]ReplicationController) @protobuf(2,bytes,rep)
}

// Session Affinity Type string
// +enum
#ServiceAffinity: string // #enumServiceAffinity

#enumServiceAffinity:
	#ServiceAffinityClientIP |
	#ServiceAffinityNone

// ServiceAffinityClientIP is the Client IP based.
#ServiceAffinityClientIP: #ServiceAffinity & "ClientIP"

// ServiceAffinityNone - no session affinity.
#ServiceAffinityNone: #ServiceAffinity & "None"

#DefaultClientIPServiceAffinitySeconds: int32 & 10800

// SessionAffinityConfig represents the configurations of session affinity.
#SessionAffinityConfig: {
	// clientIP contains the configurations of Client IP based session affinity.
	// +optional
	clientIP?: null | #ClientIPConfig @go(ClientIP,*ClientIPConfig) @protobuf(1,bytes,opt)
}

// ClientIPConfig represents the configurations of Client IP based session affinity.
#ClientIPConfig: {
	// 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).
	// +optional
	timeoutSeconds?: null | int32 @go(TimeoutSeconds,*int32) @protobuf(1,varint,opt)
}

// Service Type string describes ingress methods for a service
// +enum
#ServiceType: string // #enumServiceType

#enumServiceType:
	#ServiceTypeClusterIP |
	#ServiceTypeNodePort |
	#ServiceTypeLoadBalancer |
	#ServiceTypeExternalName

// ServiceTypeClusterIP means a service will only be accessible inside the
// cluster, via the cluster IP.
#ServiceTypeClusterIP: #ServiceType & "ClusterIP"

// ServiceTypeNodePort means a service will be exposed on one port of
// every node, in addition to 'ClusterIP' type.
#ServiceTypeNodePort: #ServiceType & "NodePort"

// ServiceTypeLoadBalancer means a service will be exposed via an
// external load balancer (if the cloud provider supports it), in addition
// to 'NodePort' type.
#ServiceTypeLoadBalancer: #ServiceType & "LoadBalancer"

// ServiceTypeExternalName 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.
#ServiceTypeExternalName: #ServiceType & "ExternalName"

// ServiceInternalTrafficPolicyType describes the type of traffic routing for
// internal traffic
// +enum
#ServiceInternalTrafficPolicyType: string // #enumServiceInternalTrafficPolicyType

#enumServiceInternalTrafficPolicyType:
	#ServiceInternalTrafficPolicyCluster |
	#ServiceInternalTrafficPolicyLocal

// ServiceInternalTrafficPolicyCluster routes traffic to all endpoints
#ServiceInternalTrafficPolicyCluster: #ServiceInternalTrafficPolicyType & "Cluster"

// ServiceInternalTrafficPolicyLocal only routes to node-local
// endpoints, otherwise drops the traffic
#ServiceInternalTrafficPolicyLocal: #ServiceInternalTrafficPolicyType & "Local"

// Service External Traffic Policy Type string
// +enum
#ServiceExternalTrafficPolicyType: string // #enumServiceExternalTrafficPolicyType

#enumServiceExternalTrafficPolicyType:
	#ServiceExternalTrafficPolicyTypeLocal |
	#ServiceExternalTrafficPolicyTypeCluster

// ServiceExternalTrafficPolicyTypeLocal specifies node-local endpoints behavior.
#ServiceExternalTrafficPolicyTypeLocal: #ServiceExternalTrafficPolicyType & "Local"

// ServiceExternalTrafficPolicyTypeCluster specifies node-global (legacy) behavior.
#ServiceExternalTrafficPolicyTypeCluster: #ServiceExternalTrafficPolicyType & "Cluster"

// LoadBalancerPortsError represents the condition of the requested ports
// on the cloud load balancer instance.
#LoadBalancerPortsError: "LoadBalancerPortsError"

// ServiceStatus represents the current status of a service.
#ServiceStatus: {
	// LoadBalancer contains the current status of the load-balancer,
	// if one is present.
	// +optional
	loadBalancer?: #LoadBalancerStatus @go(LoadBalancer) @protobuf(1,bytes,opt)

	// Current service state
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=type
	conditions?: [...metav1.#Condition] @go(Conditions,[]metav1.Condition) @protobuf(2,bytes,rep)
}

// LoadBalancerStatus represents the status of a load-balancer.
#LoadBalancerStatus: {
	// Ingress is a list containing ingress points for the load-balancer.
	// Traffic intended for the service should be sent to these ingress points.
	// +optional
	ingress?: [...#LoadBalancerIngress] @go(Ingress,[]LoadBalancerIngress) @protobuf(1,bytes,rep)
}

// LoadBalancerIngress represents the status of a load-balancer ingress point:
// traffic intended for the service should be sent to an ingress point.
#LoadBalancerIngress: {
	// IP is set for load-balancer ingress points that are IP based
	// (typically GCE or OpenStack load-balancers)
	// +optional
	ip?: string @go(IP) @protobuf(1,bytes,opt)

	// Hostname is set for load-balancer ingress points that are DNS based
	// (typically AWS load-balancers)
	// +optional
	hostname?: string @go(Hostname) @protobuf(2,bytes,opt)

	// Ports is a list of records of service ports
	// If used, every port defined in the service should have an entry in it
	// +listType=atomic
	// +optional
	ports?: [...#PortStatus] @go(Ports,[]PortStatus) @protobuf(4,bytes,rep)
}

// IPFamily represents the IP Family (IPv4 or IPv6). This type is used
// to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies).
// +enum
#IPFamily: string // #enumIPFamily

#enumIPFamily:
	#IPv4Protocol |
	#IPv6Protocol

// IPv4Protocol indicates that this IP is IPv4 protocol
#IPv4Protocol: #IPFamily & "IPv4"

// IPv6Protocol indicates that this IP is IPv6 protocol
#IPv6Protocol: #IPFamily & "IPv6"

// IPFamilyPolicyType represents the dual-stack-ness requested or required by a Service
// +enum
#IPFamilyPolicyType: string // #enumIPFamilyPolicyType

#enumIPFamilyPolicyType:
	#IPFamilyPolicySingleStack |
	#IPFamilyPolicyPreferDualStack |
	#IPFamilyPolicyRequireDualStack

// IPFamilyPolicySingleStack indicates that this service is required to have a single IPFamily.
// The IPFamily assigned is based on the default IPFamily used by the cluster
// or as identified by service.spec.ipFamilies field
#IPFamilyPolicySingleStack: #IPFamilyPolicyType & "SingleStack"

// IPFamilyPolicyPreferDualStack indicates that this service prefers dual-stack when
// the cluster is configured for dual-stack. If the cluster is not configured
// for dual-stack the service will be assigned a single IPFamily. If the IPFamily is not
// set in service.spec.ipFamilies then the service will be assigned the default IPFamily
// configured on the cluster
#IPFamilyPolicyPreferDualStack: #IPFamilyPolicyType & "PreferDualStack"

// IPFamilyPolicyRequireDualStack indicates that this service requires dual-stack. Using
// IPFamilyPolicyRequireDualStack on a single stack cluster will result in validation errors. The
// IPFamilies (and their order) assigned  to this service is based on service.spec.ipFamilies. If
// service.spec.ipFamilies was not provided then it will be assigned according to how they are
// configured on the cluster. If service.spec.ipFamilies has only one entry then the alternative
// IPFamily will be added by apiserver
#IPFamilyPolicyRequireDualStack: #IPFamilyPolicyType & "RequireDualStack"

// ServiceSpec describes the attributes that a user creates on a service.
#ServiceSpec: {
	// 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
	// +patchMergeKey=port
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=port
	// +listMapKey=protocol
	ports?: [...#ServicePort] @go(Ports,[]ServicePort) @protobuf(1,bytes,rep)

	// 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/
	// +optional
	// +mapType=atomic
	selector?: {[string]: string} @go(Selector,map[string]string) @protobuf(2,bytes,rep)

	// 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
	// +optional
	clusterIP?: string @go(ClusterIP) @protobuf(3,bytes,opt)

	// 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
	// +listType=atomic
	// +optional
	clusterIPs?: [...string] @go(ClusterIPs,[]string) @protobuf(18,bytes,opt)

	// 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
	// +optional
	type?: #ServiceType @go(Type) @protobuf(4,bytes,opt,casttype=ServiceType)

	// 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.
	// +optional
	externalIPs?: [...string] @go(ExternalIPs,[]string) @protobuf(5,bytes,rep)

	// 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
	// +optional
	sessionAffinity?: #ServiceAffinity @go(SessionAffinity) @protobuf(7,bytes,opt,casttype=ServiceAffinity)

	// 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.
	// +optional
	loadBalancerIP?: string @go(LoadBalancerIP) @protobuf(8,bytes,opt)

	// 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/
	// +optional
	loadBalancerSourceRanges?: [...string] @go(LoadBalancerSourceRanges,[]string) @protobuf(9,bytes,opt)

	// 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".
	// +optional
	externalName?: string @go(ExternalName) @protobuf(10,bytes,opt)

	// 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.
	// +optional
	externalTrafficPolicy?: #ServiceExternalTrafficPolicyType @go(ExternalTrafficPolicy) @protobuf(11,bytes,opt)

	// 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).
	// +optional
	healthCheckNodePort?: int32 @go(HealthCheckNodePort) @protobuf(12,bytes,opt)

	// 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.
	// +optional
	publishNotReadyAddresses?: bool @go(PublishNotReadyAddresses) @protobuf(13,varint,opt)

	// sessionAffinityConfig contains the configurations of session affinity.
	// +optional
	sessionAffinityConfig?: null | #SessionAffinityConfig @go(SessionAffinityConfig,*SessionAffinityConfig) @protobuf(14,bytes,opt)

	// 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.
	// +listType=atomic
	// +optional
	ipFamilies?: [...#IPFamily] @go(IPFamilies,[]IPFamily) @protobuf(19,bytes,opt,casttype=IPFamily)

	// 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.
	// +optional
	ipFamilyPolicy?: null | #IPFamilyPolicyType @go(IPFamilyPolicy,*IPFamilyPolicyType) @protobuf(17,bytes,opt,casttype=IPFamilyPolicyType)

	// 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.
	// +featureGate=ServiceLBNodePortControl
	// +optional
	allocateLoadBalancerNodePorts?: null | bool @go(AllocateLoadBalancerNodePorts,*bool) @protobuf(20,bytes,opt)

	// 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.
	// +featureGate=LoadBalancerClass
	// +optional
	loadBalancerClass?: null | string @go(LoadBalancerClass,*string) @protobuf(21,bytes,opt)

	// 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".
	// +featureGate=ServiceInternalTrafficPolicy
	// +optional
	internalTrafficPolicy?: null | #ServiceInternalTrafficPolicyType @go(InternalTrafficPolicy,*ServiceInternalTrafficPolicyType) @protobuf(22,bytes,opt)
}

// ServicePort contains information on service's port.
#ServicePort: {
	// 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.
	// +optional
	name?: string @go(Name) @protobuf(1,bytes,opt)

	// The IP protocol for this port. Supports "TCP", "UDP", and "SCTP".
	// Default is TCP.
	// +default="TCP"
	// +optional
	protocol?: #Protocol @go(Protocol) @protobuf(2,bytes,opt,casttype=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.
	// +optional
	appProtocol?: null | string @go(AppProtocol,*string) @protobuf(6,bytes,opt)

	// The port that will be exposed by this service.
	port: int32 @go(Port) @protobuf(3,varint,opt)

	// 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
	// +optional
	targetPort?: intstr.#IntOrString @go(TargetPort) @protobuf(4,bytes,opt)

	// 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
	// +optional
	nodePort?: int32 @go(NodePort) @protobuf(5,varint,opt)
}

// 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.
#Service: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Spec defines the behavior of a service.
	// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	spec?: #ServiceSpec @go(Spec) @protobuf(2,bytes,opt)

	// Most recently observed status of the service.
	// Populated by the system.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #ServiceStatus @go(Status) @protobuf(3,bytes,opt)
}

// ClusterIPNone - do not assign a cluster IP
// no proxying required and no environment variables should be created for pods
#ClusterIPNone: "None"

// ServiceList holds a list of services.
#ServiceList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of services
	items: [...#Service] @go(Items,[]Service) @protobuf(2,bytes,rep)
}

// 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
#ServiceAccount: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge
	secrets?: [...#ObjectReference] @go(Secrets,[]ObjectReference) @protobuf(2,bytes,rep)

	// 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
	// +optional
	imagePullSecrets?: [...#LocalObjectReference] @go(ImagePullSecrets,[]LocalObjectReference) @protobuf(3,bytes,rep)

	// AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted.
	// Can be overridden at the pod level.
	// +optional
	automountServiceAccountToken?: null | bool @go(AutomountServiceAccountToken,*bool) @protobuf(4,varint,opt)
}

// ServiceAccountList is a list of ServiceAccount objects
#ServiceAccountList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of ServiceAccounts.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	items: [...#ServiceAccount] @go(Items,[]ServiceAccount) @protobuf(2,bytes,rep)
}

// 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}]
//     },
//  ]
#Endpoints: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	subsets?: [...#EndpointSubset] @go(Subsets,[]EndpointSubset) @protobuf(2,bytes,rep)
}

// 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 ]
#EndpointSubset: {
	// 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.
	// +optional
	addresses?: [...#EndpointAddress] @go(Addresses,[]EndpointAddress) @protobuf(1,bytes,rep)

	// 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.
	// +optional
	notReadyAddresses?: [...#EndpointAddress] @go(NotReadyAddresses,[]EndpointAddress) @protobuf(2,bytes,rep)

	// Port numbers available on the related IP addresses.
	// +optional
	ports?: [...#EndpointPort] @go(Ports,[]EndpointPort) @protobuf(3,bytes,rep)
}

// EndpointAddress is a tuple that describes single IP address.
// +structType=atomic
#EndpointAddress: {
	// 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.
	// TODO: This should allow hostname or IP, See #4447.
	ip: string @go(IP) @protobuf(1,bytes,opt)

	// The Hostname of this endpoint
	// +optional
	hostname?: string @go(Hostname) @protobuf(3,bytes,opt)

	// Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.
	// +optional
	nodeName?: null | string @go(NodeName,*string) @protobuf(4,bytes,opt)

	// Reference to object providing the endpoint.
	// +optional
	targetRef?: null | #ObjectReference @go(TargetRef,*ObjectReference) @protobuf(2,bytes,opt)
}

// EndpointPort is a tuple that describes a single port.
// +structType=atomic
#EndpointPort: {
	// 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.
	// +optional
	name?: string @go(Name) @protobuf(1,bytes,opt)

	// The port number of the endpoint.
	port: int32 @go(Port) @protobuf(2,varint,opt)

	// The IP protocol for this port.
	// Must be UDP, TCP, or SCTP.
	// Default is TCP.
	// +optional
	protocol?: #Protocol @go(Protocol) @protobuf(3,bytes,opt,casttype=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.
	// +optional
	appProtocol?: null | string @go(AppProtocol,*string) @protobuf(4,bytes,opt)
}

// EndpointsList is a list of endpoints.
#EndpointsList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of endpoints.
	items: [...#Endpoints] @go(Items,[]Endpoints) @protobuf(2,bytes,rep)
}

// NodeSpec describes the attributes that a node is created with.
#NodeSpec: {
	// PodCIDR represents the pod IP range assigned to the node.
	// +optional
	podCIDR?: string @go(PodCIDR) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	// +patchStrategy=merge
	podCIDRs?: [...string] @go(PodCIDRs,[]string) @protobuf(7,bytes,opt)

	// ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>
	// +optional
	providerID?: string @go(ProviderID) @protobuf(3,bytes,opt)

	// Unschedulable controls node schedulability of new pods. By default, node is schedulable.
	// More info: https://kubernetes.io/docs/concepts/nodes/node/#manual-node-administration
	// +optional
	unschedulable?: bool @go(Unschedulable) @protobuf(4,varint,opt)

	// If specified, the node's taints.
	// +optional
	taints?: [...#Taint] @go(Taints,[]Taint) @protobuf(5,bytes,opt)

	// 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
	// +optional
	configSource?: null | #NodeConfigSource @go(ConfigSource,*NodeConfigSource) @protobuf(6,bytes,opt)

	// Deprecated. Not all kubelets will set this field. Remove field after 1.13.
	// see: https://issues.k8s.io/61966
	// +optional
	externalID?: string @go(DoNotUseExternalID) @protobuf(2,bytes,opt)
}

// NodeConfigSource specifies a source of node configuration. Exactly one subfield (excluding metadata) must be non-nil.
// This API is deprecated since 1.22
#NodeConfigSource: {
	// ConfigMap is a reference to a Node's ConfigMap
	configMap?: null | #ConfigMapNodeConfigSource @go(ConfigMap,*ConfigMapNodeConfigSource) @protobuf(2,bytes,opt)
}

// 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
#ConfigMapNodeConfigSource: {
	// Namespace is the metadata.namespace of the referenced ConfigMap.
	// This field is required in all cases.
	namespace: string @go(Namespace) @protobuf(1,bytes,opt)

	// Name is the metadata.name of the referenced ConfigMap.
	// This field is required in all cases.
	name: string @go(Name) @protobuf(2,bytes,opt)

	// UID is the metadata.UID of the referenced ConfigMap.
	// This field is forbidden in Node.Spec, and required in Node.Status.
	// +optional
	uid?: types.#UID @go(UID) @protobuf(3,bytes,opt)

	// ResourceVersion is the metadata.ResourceVersion of the referenced ConfigMap.
	// This field is forbidden in Node.Spec, and required in Node.Status.
	// +optional
	resourceVersion?: string @go(ResourceVersion) @protobuf(4,bytes,opt)

	// KubeletConfigKey declares which key of the referenced ConfigMap corresponds to the KubeletConfiguration structure
	// This field is required in all cases.
	kubeletConfigKey: string @go(KubeletConfigKey) @protobuf(5,bytes,opt)
}

// DaemonEndpoint contains information about a single Daemon endpoint.
#DaemonEndpoint: {
	// Port number of the given endpoint.
	Port: int32 @protobuf(1,varint,opt)
}

// NodeDaemonEndpoints lists ports opened by daemons running on the Node.
#NodeDaemonEndpoints: {
	// Endpoint on which Kubelet is listening.
	// +optional
	kubeletEndpoint?: #DaemonEndpoint @go(KubeletEndpoint) @protobuf(1,bytes,opt)
}

// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
#NodeSystemInfo: {
	// MachineID reported by the node. For unique machine identification
	// in the cluster this field is preferred. Learn more from man(5)
	// machine-id: http://man7.org/linux/man-pages/man5/machine-id.5.html
	machineID: string @go(MachineID) @protobuf(1,bytes,opt)

	// SystemUUID reported by the node. For unique machine identification
	// MachineID is preferred. This field is specific to Red Hat hosts
	// https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid
	systemUUID: string @go(SystemUUID) @protobuf(2,bytes,opt)

	// Boot ID reported by the node.
	bootID: string @go(BootID) @protobuf(3,bytes,opt)

	// Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64).
	kernelVersion: string @go(KernelVersion) @protobuf(4,bytes,opt)

	// OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)).
	osImage: string @go(OSImage) @protobuf(5,bytes,opt)

	// ContainerRuntime Version reported by the node through runtime remote API (e.g. docker://1.5.0).
	containerRuntimeVersion: string @go(ContainerRuntimeVersion) @protobuf(6,bytes,opt)

	// Kubelet Version reported by the node.
	kubeletVersion: string @go(KubeletVersion) @protobuf(7,bytes,opt)

	// KubeProxy Version reported by the node.
	kubeProxyVersion: string @go(KubeProxyVersion) @protobuf(8,bytes,opt)

	// The Operating System reported by the node
	operatingSystem: string @go(OperatingSystem) @protobuf(9,bytes,opt)

	// The Architecture reported by the node
	architecture: string @go(Architecture) @protobuf(10,bytes,opt)
}

// NodeConfigStatus describes the status of the config assigned by Node.Spec.ConfigSource.
#NodeConfigStatus: {
	// Assigned reports the checkpointed config the node will try to use.
	// When Node.Spec.ConfigSource is updated, the node checkpoints the associated
	// config payload to local disk, along with a record indicating intended
	// config. The node refers to this record to choose its config checkpoint, and
	// reports this record in Assigned. Assigned only updates in the status after
	// the record has been checkpointed to disk. When the Kubelet is restarted,
	// it tries to make the Assigned config the Active config by loading and
	// validating the checkpointed payload identified by Assigned.
	// +optional
	assigned?: null | #NodeConfigSource @go(Assigned,*NodeConfigSource) @protobuf(1,bytes,opt)

	// Active reports the checkpointed config the node is actively using.
	// Active will represent either the current version of the Assigned config,
	// or the current LastKnownGood config, depending on whether attempting to use the
	// Assigned config results in an error.
	// +optional
	active?: null | #NodeConfigSource @go(Active,*NodeConfigSource) @protobuf(2,bytes,opt)

	// LastKnownGood reports the checkpointed config the node will fall back to
	// when it encounters an error attempting to use the Assigned config.
	// The Assigned config becomes the LastKnownGood config when the node determines
	// that the Assigned config is stable and correct.
	// This is currently implemented as a 10-minute soak period starting when the local
	// record of Assigned config is updated. If the Assigned config is Active at the end
	// of this period, it becomes the LastKnownGood. Note that if Spec.ConfigSource is
	// reset to nil (use local defaults), the LastKnownGood is also immediately reset to nil,
	// because the local default config is always assumed good.
	// You should not make assumptions about the node's method of determining config stability
	// and correctness, as this may change or become configurable in the future.
	// +optional
	lastKnownGood?: null | #NodeConfigSource @go(LastKnownGood,*NodeConfigSource) @protobuf(3,bytes,opt)

	// Error describes any problems reconciling the Spec.ConfigSource to the Active config.
	// Errors may occur, for example, attempting to checkpoint Spec.ConfigSource to the local Assigned
	// record, attempting to checkpoint the payload associated with Spec.ConfigSource, attempting
	// to load or validate the Assigned config, etc.
	// Errors may occur at different points while syncing config. Earlier errors (e.g. download or
	// checkpointing errors) will not result in a rollback to LastKnownGood, and may resolve across
	// Kubelet retries. Later errors (e.g. loading or validating a checkpointed config) will result in
	// a rollback to LastKnownGood. In the latter case, it is usually possible to resolve the error
	// by fixing the config assigned in Spec.ConfigSource.
	// You can find additional information for debugging by searching the error message in the Kubelet log.
	// Error is a human-readable description of the error state; machines can check whether or not Error
	// is empty, but should not rely on the stability of the Error text across Kubelet versions.
	// +optional
	error?: string @go(Error) @protobuf(4,bytes,opt)
}

// NodeStatus is information about the current status of a node.
#NodeStatus: {
	// Capacity represents the total resources of a node.
	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#capacity
	// +optional
	capacity?: #ResourceList @go(Capacity) @protobuf(1,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// Allocatable represents the resources of a node that are available for scheduling.
	// Defaults to Capacity.
	// +optional
	allocatable?: #ResourceList @go(Allocatable) @protobuf(2,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// NodePhase is the recently observed lifecycle phase of the node.
	// More info: https://kubernetes.io/docs/concepts/nodes/node/#phase
	// The field is never populated, and now is deprecated.
	// +optional
	phase?: #NodePhase @go(Phase) @protobuf(3,bytes,opt,casttype=NodePhase)

	// Conditions is an array of current observed node conditions.
	// More info: https://kubernetes.io/docs/concepts/nodes/node/#condition
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	conditions?: [...#NodeCondition] @go(Conditions,[]NodeCondition) @protobuf(4,bytes,rep)

	// List of addresses reachable to the node.
	// Queried from cloud provider, if available.
	// More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses
	// Note: This field is declared as mergeable, but the merge key is not sufficiently
	// unique, which can cause data corruption when it is merged. Callers should instead
	// use a full-replacement patch. See http://pr.k8s.io/79391 for an example.
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	addresses?: [...#NodeAddress] @go(Addresses,[]NodeAddress) @protobuf(5,bytes,rep)

	// Endpoints of daemons running on the Node.
	// +optional
	daemonEndpoints?: #NodeDaemonEndpoints @go(DaemonEndpoints) @protobuf(6,bytes,opt)

	// Set of ids/uuids to uniquely identify the node.
	// More info: https://kubernetes.io/docs/concepts/nodes/node/#info
	// +optional
	nodeInfo?: #NodeSystemInfo @go(NodeInfo) @protobuf(7,bytes,opt)

	// List of container images on this node
	// +optional
	images?: [...#ContainerImage] @go(Images,[]ContainerImage) @protobuf(8,bytes,rep)

	// List of attachable volumes in use (mounted) by the node.
	// +optional
	volumesInUse?: [...#UniqueVolumeName] @go(VolumesInUse,[]UniqueVolumeName) @protobuf(9,bytes,rep)

	// List of volumes that are attached to the node.
	// +optional
	volumesAttached?: [...#AttachedVolume] @go(VolumesAttached,[]AttachedVolume) @protobuf(10,bytes,rep)

	// Status of the config assigned to the node via the dynamic Kubelet config feature.
	// +optional
	config?: null | #NodeConfigStatus @go(Config,*NodeConfigStatus) @protobuf(11,bytes,opt)
}

#UniqueVolumeName: string

// AttachedVolume describes a volume attached to a node
#AttachedVolume: {
	// Name of the attached volume
	name: #UniqueVolumeName @go(Name) @protobuf(1,bytes,rep)

	// DevicePath represents the device path where the volume should be available
	devicePath: string @go(DevicePath) @protobuf(2,bytes,rep)
}

// AvoidPods describes pods that should avoid this node. This is the value for a
// Node annotation with key scheduler.alpha.kubernetes.io/preferAvoidPods and
// will eventually become a field of NodeStatus.
#AvoidPods: {
	// Bounded-sized list of signatures of pods that should avoid this node, sorted
	// in timestamp order from oldest to newest. Size of the slice is unspecified.
	// +optional
	preferAvoidPods?: [...#PreferAvoidPodsEntry] @go(PreferAvoidPods,[]PreferAvoidPodsEntry) @protobuf(1,bytes,rep)
}

// Describes a class of pods that should avoid this node.
#PreferAvoidPodsEntry: {
	// The class of pods.
	podSignature: #PodSignature @go(PodSignature) @protobuf(1,bytes,opt)

	// Time at which this entry was added to the list.
	// +optional
	evictionTime?: metav1.#Time @go(EvictionTime) @protobuf(2,bytes,opt)

	// (brief) reason why this entry was added to the list.
	// +optional
	reason?: string @go(Reason) @protobuf(3,bytes,opt)

	// Human readable message indicating why this entry was added to the list.
	// +optional
	message?: string @go(Message) @protobuf(4,bytes,opt)
}

// Describes the class of pods that should avoid this node.
// Exactly one field should be set.
#PodSignature: {
	// Reference to controller whose pods should avoid this node.
	// +optional
	podController?: null | metav1.#OwnerReference @go(PodController,*metav1.OwnerReference) @protobuf(1,bytes,opt)
}

// Describe a container image
#ContainerImage: {
	// Names by which this image is known.
	// e.g. ["k8s.gcr.io/hyperkube:v1.0.7", "dockerhub.io/google_containers/hyperkube:v1.0.7"]
	// +optional
	names: [...string] @go(Names,[]string) @protobuf(1,bytes,rep)

	// The size of the image in bytes.
	// +optional
	sizeBytes?: int64 @go(SizeBytes) @protobuf(2,varint,opt)
}

// +enum
#NodePhase: string // #enumNodePhase

#enumNodePhase:
	#NodePending |
	#NodeRunning |
	#NodeTerminated

// NodePending means the node has been created/added by the system, but not configured.
#NodePending: #NodePhase & "Pending"

// NodeRunning means the node has been configured and has Kubernetes components running.
#NodeRunning: #NodePhase & "Running"

// NodeTerminated means the node has been removed from the cluster.
#NodeTerminated: #NodePhase & "Terminated"

// +enum
#NodeConditionType: string // #enumNodeConditionType

#enumNodeConditionType:
	#NodeReady |
	#NodeMemoryPressure |
	#NodeDiskPressure |
	#NodePIDPressure |
	#NodeNetworkUnavailable

// NodeReady means kubelet is healthy and ready to accept pods.
#NodeReady: #NodeConditionType & "Ready"

// NodeMemoryPressure means the kubelet is under pressure due to insufficient available memory.
#NodeMemoryPressure: #NodeConditionType & "MemoryPressure"

// NodeDiskPressure means the kubelet is under pressure due to insufficient available disk.
#NodeDiskPressure: #NodeConditionType & "DiskPressure"

// NodePIDPressure means the kubelet is under pressure due to insufficient available PID.
#NodePIDPressure: #NodeConditionType & "PIDPressure"

// NodeNetworkUnavailable means that network for the node is not correctly configured.
#NodeNetworkUnavailable: #NodeConditionType & "NetworkUnavailable"

// NodeCondition contains condition information for a node.
#NodeCondition: {
	// Type of node condition.
	type: #NodeConditionType @go(Type) @protobuf(1,bytes,opt,casttype=NodeConditionType)

	// Status of the condition, one of True, False, Unknown.
	status: #ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=ConditionStatus)

	// Last time we got an update on a given condition.
	// +optional
	lastHeartbeatTime?: metav1.#Time @go(LastHeartbeatTime) @protobuf(3,bytes,opt)

	// Last time the condition transit from one status to another.
	// +optional
	lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(4,bytes,opt)

	// (brief) reason for the condition's last transition.
	// +optional
	reason?: string @go(Reason) @protobuf(5,bytes,opt)

	// Human readable message indicating details about last transition.
	// +optional
	message?: string @go(Message) @protobuf(6,bytes,opt)
}

// +enum
#NodeAddressType: string // #enumNodeAddressType

#enumNodeAddressType:
	#NodeHostName |
	#NodeInternalIP |
	#NodeExternalIP |
	#NodeInternalDNS |
	#NodeExternalDNS

// NodeHostName identifies a name of the node. Although every node can be assumed
// to have a NodeAddress of this type, its exact syntax and semantics are not
// defined, and are not consistent between different clusters.
#NodeHostName: #NodeAddressType & "Hostname"

// NodeInternalIP identifies an IP address which is assigned to one of the node's
// network interfaces. Every node should have at least one address of this type.
//
// An internal IP is normally expected to be reachable from every other node, but
// may not be visible to hosts outside the cluster. By default it is assumed that
// kube-apiserver can reach node internal IPs, though it is possible to configure
// clusters where this is not the case.
//
// NodeInternalIP is the default type of node IP, and does not necessarily imply
// that the IP is ONLY reachable internally. If a node has multiple internal IPs,
// no specific semantics are assigned to the additional IPs.
#NodeInternalIP: #NodeAddressType & "InternalIP"

// NodeExternalIP identifies an IP address which is, in some way, intended to be
// more usable from outside the cluster then an internal IP, though no specific
// semantics are defined. It may be a globally routable IP, though it is not
// required to be.
//
// External IPs may be assigned directly to an interface on the node, like a
// NodeInternalIP, or alternatively, packets sent to the external IP may be NAT'ed
// to an internal node IP rather than being delivered directly (making the IP less
// efficient for node-to-node traffic than a NodeInternalIP).
#NodeExternalIP: #NodeAddressType & "ExternalIP"

// NodeInternalDNS identifies a DNS name which resolves to an IP address which has
// the characteristics of a NodeInternalIP. The IP it resolves to may or may not
// be a listed NodeInternalIP address.
#NodeInternalDNS: #NodeAddressType & "InternalDNS"

// NodeExternalDNS identifies a DNS name which resolves to an IP address which has
// the characteristics of a NodeExternalIP. The IP it resolves to may or may not
// be a listed NodeExternalIP address.
#NodeExternalDNS: #NodeAddressType & "ExternalDNS"

// NodeAddress contains information for the node's address.
#NodeAddress: {
	// Node address type, one of Hostname, ExternalIP or InternalIP.
	type: #NodeAddressType @go(Type) @protobuf(1,bytes,opt,casttype=NodeAddressType)

	// The node address.
	address: string @go(Address) @protobuf(2,bytes,opt)
}

// ResourceName is the name identifying various resources in a ResourceList.
#ResourceName: string // #enumResourceName

#enumResourceName:
	#ResourceCPU |
	#ResourceMemory |
	#ResourceStorage |
	#ResourceEphemeralStorage |
	#ResourcePods |
	#ResourceServices |
	#ResourceReplicationControllers |
	#ResourceQuotas |
	#ResourceSecrets |
	#ResourceConfigMaps |
	#ResourcePersistentVolumeClaims |
	#ResourceServicesNodePorts |
	#ResourceServicesLoadBalancers |
	#ResourceRequestsCPU |
	#ResourceRequestsMemory |
	#ResourceRequestsStorage |
	#ResourceRequestsEphemeralStorage |
	#ResourceLimitsCPU |
	#ResourceLimitsMemory |
	#ResourceLimitsEphemeralStorage

// CPU, in cores. (500m = .5 cores)
#ResourceCPU: #ResourceName & "cpu"

// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
#ResourceMemory: #ResourceName & "memory"

// Volume size, in bytes (e,g. 5Gi = 5GiB = 5 * 1024 * 1024 * 1024)
#ResourceStorage: #ResourceName & "storage"

// Local ephemeral storage, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
// The resource name for ResourceEphemeralStorage is alpha and it can change across releases.
#ResourceEphemeralStorage: #ResourceName & "ephemeral-storage"

// Default namespace prefix.
#ResourceDefaultNamespacePrefix: "kubernetes.io/"

// Name prefix for huge page resources (alpha).
#ResourceHugePagesPrefix: "hugepages-"

// Name prefix for storage resource limits
#ResourceAttachableVolumesPrefix: "attachable-volumes-"

// ResourceList is a set of (resource name, quantity) pairs.
#ResourceList: {[string]: resource.#Quantity}

// Node is a worker node in Kubernetes.
// Each node will have a unique identifier in the cache (i.e. in etcd).
#Node: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Spec defines the behavior of a node.
	// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	spec?: #NodeSpec @go(Spec) @protobuf(2,bytes,opt)

	// Most recently observed status of the node.
	// Populated by the system.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #NodeStatus @go(Status) @protobuf(3,bytes,opt)
}

// NodeList is the whole list of all Nodes which have been registered with master.
#NodeList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of nodes
	items: [...#Node] @go(Items,[]Node) @protobuf(2,bytes,rep)
}

// FinalizerName is the name identifying a finalizer during namespace lifecycle.
#FinalizerName: string // #enumFinalizerName

#enumFinalizerName:
	#FinalizerKubernetes

#FinalizerKubernetes: #FinalizerName & "kubernetes"

// NamespaceSpec describes the attributes on a Namespace.
#NamespaceSpec: {
	// 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/
	// +optional
	finalizers?: [...#FinalizerName] @go(Finalizers,[]FinalizerName) @protobuf(1,bytes,rep,casttype=FinalizerName)
}

// NamespaceStatus is information about the current status of a Namespace.
#NamespaceStatus: {
	// Phase is the current lifecycle phase of the namespace.
	// More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
	// +optional
	phase?: #NamespacePhase @go(Phase) @protobuf(1,bytes,opt,casttype=NamespacePhase)

	// Represents the latest available observations of a namespace's current state.
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	conditions?: [...#NamespaceCondition] @go(Conditions,[]NamespaceCondition) @protobuf(2,bytes,rep)
}

// +enum
#NamespacePhase: string // #enumNamespacePhase

#enumNamespacePhase:
	#NamespaceActive |
	#NamespaceTerminating

// NamespaceActive means the namespace is available for use in the system
#NamespaceActive: #NamespacePhase & "Active"

// NamespaceTerminating means the namespace is undergoing graceful termination
#NamespaceTerminating: #NamespacePhase & "Terminating"

// NamespaceTerminatingCause is returned as a defaults.cause item when a change is
// forbidden due to the namespace being terminated.
#NamespaceTerminatingCause: metav1.#CauseType & "NamespaceTerminating"

// +enum
#NamespaceConditionType: string // #enumNamespaceConditionType

#enumNamespaceConditionType:
	#NamespaceDeletionDiscoveryFailure |
	#NamespaceDeletionContentFailure |
	#NamespaceDeletionGVParsingFailure |
	#NamespaceContentRemaining |
	#NamespaceFinalizersRemaining

// NamespaceDeletionDiscoveryFailure contains information about namespace deleter errors during resource discovery.
#NamespaceDeletionDiscoveryFailure: #NamespaceConditionType & "NamespaceDeletionDiscoveryFailure"

// NamespaceDeletionContentFailure contains information about namespace deleter errors during deletion of resources.
#NamespaceDeletionContentFailure: #NamespaceConditionType & "NamespaceDeletionContentFailure"

// NamespaceDeletionGVParsingFailure contains information about namespace deleter errors parsing GV for legacy types.
#NamespaceDeletionGVParsingFailure: #NamespaceConditionType & "NamespaceDeletionGroupVersionParsingFailure"

// NamespaceContentRemaining contains information about resources remaining in a namespace.
#NamespaceContentRemaining: #NamespaceConditionType & "NamespaceContentRemaining"

// NamespaceFinalizersRemaining contains information about which finalizers are on resources remaining in a namespace.
#NamespaceFinalizersRemaining: #NamespaceConditionType & "NamespaceFinalizersRemaining"

// NamespaceCondition contains details about state of namespace.
#NamespaceCondition: {
	// Type of namespace controller condition.
	type: #NamespaceConditionType @go(Type) @protobuf(1,bytes,opt,casttype=NamespaceConditionType)

	// Status of the condition, one of True, False, Unknown.
	status: #ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=ConditionStatus)

	// +optional
	lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(4,bytes,opt)

	// +optional
	reason?: string @go(Reason) @protobuf(5,bytes,opt)

	// +optional
	message?: string @go(Message) @protobuf(6,bytes,opt)
}

// Namespace provides a scope for Names.
// Use of multiple namespaces is optional.
#Namespace: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Spec defines the behavior of the Namespace.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	spec?: #NamespaceSpec @go(Spec) @protobuf(2,bytes,opt)

	// Status describes the current status of a Namespace.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #NamespaceStatus @go(Status) @protobuf(3,bytes,opt)
}

// NamespaceList is a list of Namespaces.
#NamespaceList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// Items is the list of Namespace objects in the list.
	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
	items: [...#Namespace] @go(Items,[]Namespace) @protobuf(2,bytes,rep)
}

// 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.
#Binding: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// The target object that you want to bind to the standard object.
	target: #ObjectReference @go(Target) @protobuf(2,bytes,opt)
}

// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
// +k8s:openapi-gen=false
#Preconditions: {
	// Specifies the target UID.
	// +optional
	uid?: null | types.#UID @go(UID,*types.UID) @protobuf(1,bytes,opt,casttype=k8s.io/apimachinery/pkg/types.UID)
}

// PodLogOptions is the query options for a Pod's logs REST call.
#PodLogOptions: {
	metav1.#TypeMeta

	// The container for which to stream logs. Defaults to only container if there is one container in the pod.
	// +optional
	container?: string @go(Container) @protobuf(1,bytes,opt)

	// Follow the log stream of the pod. Defaults to false.
	// +optional
	follow?: bool @go(Follow) @protobuf(2,varint,opt)

	// Return previous terminated container logs. Defaults to false.
	// +optional
	previous?: bool @go(Previous) @protobuf(3,varint,opt)

	// A relative time in seconds before the current time from which to show logs. If this value
	// precedes the time a pod was started, only logs since the pod start will be returned.
	// If this value is in the future, no logs will be returned.
	// Only one of sinceSeconds or sinceTime may be specified.
	// +optional
	sinceSeconds?: null | int64 @go(SinceSeconds,*int64) @protobuf(4,varint,opt)

	// An RFC3339 timestamp from which to show logs. If this value
	// precedes the time a pod was started, only logs since the pod start will be returned.
	// If this value is in the future, no logs will be returned.
	// Only one of sinceSeconds or sinceTime may be specified.
	// +optional
	sinceTime?: null | metav1.#Time @go(SinceTime,*metav1.Time) @protobuf(5,bytes,opt)

	// If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line
	// of log output. Defaults to false.
	// +optional
	timestamps?: bool @go(Timestamps) @protobuf(6,varint,opt)

	// If set, the number of lines from the end of the logs to show. If not specified,
	// logs are shown from the creation of the container or sinceSeconds or sinceTime
	// +optional
	tailLines?: null | int64 @go(TailLines,*int64) @protobuf(7,varint,opt)

	// If set, the number of bytes to read from the server before terminating the
	// log output. This may not display a complete final line of logging, and may return
	// slightly more or slightly less than the specified limit.
	// +optional
	limitBytes?: null | int64 @go(LimitBytes,*int64) @protobuf(8,varint,opt)

	// insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the
	// serving certificate of the backend it is connecting to.  This will make the HTTPS connection between the apiserver
	// and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real
	// kubelet.  If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the
	// connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept
	// the actual log data coming from the real kubelet).
	// +optional
	insecureSkipTLSVerifyBackend?: bool @go(InsecureSkipTLSVerifyBackend) @protobuf(9,varint,opt)
}

// PodAttachOptions is the query options to a Pod's remote attach call.
// ---
// TODO: merge w/ PodExecOptions below for stdin, stdout, etc
// and also when we cut V2, we should export a "StreamOptions" or somesuch that contains Stdin, Stdout, Stder and TTY
#PodAttachOptions: {
	metav1.#TypeMeta

	// Stdin if true, redirects the standard input stream of the pod for this call.
	// Defaults to false.
	// +optional
	stdin?: bool @go(Stdin) @protobuf(1,varint,opt)

	// Stdout if true indicates that stdout is to be redirected for the attach call.
	// Defaults to true.
	// +optional
	stdout?: bool @go(Stdout) @protobuf(2,varint,opt)

	// Stderr if true indicates that stderr is to be redirected for the attach call.
	// Defaults to true.
	// +optional
	stderr?: bool @go(Stderr) @protobuf(3,varint,opt)

	// TTY if true indicates that a tty will be allocated for the attach call.
	// This is passed through the container runtime so the tty
	// is allocated on the worker node by the container runtime.
	// Defaults to false.
	// +optional
	tty?: bool @go(TTY) @protobuf(4,varint,opt)

	// The container in which to execute the command.
	// Defaults to only container if there is only one container in the pod.
	// +optional
	container?: string @go(Container) @protobuf(5,bytes,opt)
}

// PodExecOptions is the query options to a Pod's remote exec call.
// ---
// TODO: This is largely identical to PodAttachOptions above, make sure they stay in sync and see about merging
// and also when we cut V2, we should export a "StreamOptions" or somesuch that contains Stdin, Stdout, Stder and TTY
#PodExecOptions: {
	metav1.#TypeMeta

	// Redirect the standard input stream of the pod for this call.
	// Defaults to false.
	// +optional
	stdin?: bool @go(Stdin) @protobuf(1,varint,opt)

	// Redirect the standard output stream of the pod for this call.
	// +optional
	stdout?: bool @go(Stdout) @protobuf(2,varint,opt)

	// Redirect the standard error stream of the pod for this call.
	// +optional
	stderr?: bool @go(Stderr) @protobuf(3,varint,opt)

	// TTY if true indicates that a tty will be allocated for the exec call.
	// Defaults to false.
	// +optional
	tty?: bool @go(TTY) @protobuf(4,varint,opt)

	// Container in which to execute the command.
	// Defaults to only container if there is only one container in the pod.
	// +optional
	container?: string @go(Container) @protobuf(5,bytes,opt)

	// Command is the remote command to execute. argv array. Not executed within a shell.
	command: [...string] @go(Command,[]string) @protobuf(6,bytes,rep)
}

// PodPortForwardOptions is the query options to a Pod's port forward call
// when using WebSockets.
// The `port` query parameter must specify the port or
// ports (comma separated) to forward over.
// Port forwarding over SPDY does not use these options. It requires the port
// to be passed in the `port` header as part of request.
#PodPortForwardOptions: {
	metav1.#TypeMeta

	// List of ports to forward
	// Required when using WebSockets
	// +optional
	ports?: [...int32] @go(Ports,[]int32) @protobuf(1,varint,rep)
}

// PodProxyOptions is the query options to a Pod's proxy call.
#PodProxyOptions: {
	metav1.#TypeMeta

	// Path is the URL path to use for the current proxy request to pod.
	// +optional
	path?: string @go(Path) @protobuf(1,bytes,opt)
}

// NodeProxyOptions is the query options to a Node's proxy call.
#NodeProxyOptions: {
	metav1.#TypeMeta

	// Path is the URL path to use for the current proxy request to node.
	// +optional
	path?: string @go(Path) @protobuf(1,bytes,opt)
}

// ServiceProxyOptions is the query options to a Service's proxy call.
#ServiceProxyOptions: {
	metav1.#TypeMeta

	// Path is the part of URLs that include service endpoints, suffixes,
	// and parameters to use for the current proxy request to service.
	// For example, the whole request URL is
	// http://localhost/api/v1/namespaces/kube-system/services/elasticsearch-logging/_search?q=user:kimchy.
	// Path is _search?q=user:kimchy.
	// +optional
	path?: string @go(Path) @protobuf(1,bytes,opt)
}

// ObjectReference contains enough information to let you inspect or modify the referred object.
// ---
// New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
//  1. Ignored fields.  It includes many fields which are not generally honored.  For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
//  2. Invalid usage help.  It is impossible to add specific help for individual usage.  In most embedded usages, there are particular
//     restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
//     Those cannot be well described when embedded.
//  3. Inconsistent validation.  Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
//  4. The fields are both imprecise and overly precise.  Kind is not a precise mapping to a URL. This can produce ambiguity
//     during interpretation and require a REST mapping.  In most cases, the dependency is on the group,resource tuple
//     and the version of the actual struct is irrelevant.
//  5. We cannot easily change it.  Because this type is embedded in many locations, updates to this type
//     will affect numerous schemas.  Don't make new APIs embed an underspecified API type they do not control.
// Instead of using this type, create a locally provided and used type that is well-focused on your reference.
// For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +structType=atomic
#ObjectReference: {
	// Kind of the referent.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	kind?: string @go(Kind) @protobuf(1,bytes,opt)

	// Namespace of the referent.
	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
	// +optional
	namespace?: string @go(Namespace) @protobuf(2,bytes,opt)

	// Name of the referent.
	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
	// +optional
	name?: string @go(Name) @protobuf(3,bytes,opt)

	// UID of the referent.
	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
	// +optional
	uid?: types.#UID @go(UID) @protobuf(4,bytes,opt,casttype=k8s.io/apimachinery/pkg/types.UID)

	// API version of the referent.
	// +optional
	apiVersion?: string @go(APIVersion) @protobuf(5,bytes,opt)

	// 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
	// +optional
	resourceVersion?: string @go(ResourceVersion) @protobuf(6,bytes,opt)

	// 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.
	// TODO: this design is not final and this field is subject to change in the future.
	// +optional
	fieldPath?: string @go(FieldPath) @protobuf(7,bytes,opt)
}

// LocalObjectReference contains enough information to let you locate the
// referenced object inside the same namespace.
// +structType=atomic
#LocalObjectReference: {
	// Name of the referent.
	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
	// TODO: Add other useful fields. apiVersion, kind, uid?
	// +optional
	name?: string @go(Name) @protobuf(1,bytes,opt)
}

// TypedLocalObjectReference contains enough information to let you locate the
// typed referenced object inside the same namespace.
// +structType=atomic
#TypedLocalObjectReference: {
	// 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.
	// +optional
	apiGroup?: null | string @go(APIGroup,*string) @protobuf(1,bytes,opt)

	// Kind is the type of resource being referenced
	kind: string @go(Kind) @protobuf(2,bytes,opt)

	// Name is the name of resource being referenced
	name: string @go(Name) @protobuf(3,bytes,opt)
}

// SerializedReference is a reference to serialized object.
#SerializedReference: {
	metav1.#TypeMeta

	// The reference to an object in the system.
	// +optional
	reference?: #ObjectReference @go(Reference) @protobuf(1,bytes,opt)
}

// EventSource contains information for an event.
#EventSource: {
	// Component from which the event is generated.
	// +optional
	component?: string @go(Component) @protobuf(1,bytes,opt)

	// Node name on which the event is generated.
	// +optional
	host?: string @go(Host) @protobuf(2,bytes,opt)
}

// Information only and will not cause any problems
#EventTypeNormal: "Normal"

// These events are to warn that something might go wrong
#EventTypeWarning: "Warning"

// Event is a report of an event somewhere in the cluster.  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.
#Event: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	metadata: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// The object that this event is about.
	involvedObject: #ObjectReference @go(InvolvedObject) @protobuf(2,bytes,opt)

	// This should be a short, machine understandable string that gives the reason
	// for the transition into the object's current status.
	// TODO: provide exact specification for format.
	// +optional
	reason?: string @go(Reason) @protobuf(3,bytes,opt)

	// A human-readable description of the status of this operation.
	// TODO: decide on maximum length.
	// +optional
	message?: string @go(Message) @protobuf(4,bytes,opt)

	// The component reporting this event. Should be a short machine understandable string.
	// +optional
	source?: #EventSource @go(Source) @protobuf(5,bytes,opt)

	// The time at which the event was first recorded. (Time of server receipt is in TypeMeta.)
	// +optional
	firstTimestamp?: metav1.#Time @go(FirstTimestamp) @protobuf(6,bytes,opt)

	// The time at which the most recent occurrence of this event was recorded.
	// +optional
	lastTimestamp?: metav1.#Time @go(LastTimestamp) @protobuf(7,bytes,opt)

	// The number of times this event has occurred.
	// +optional
	count?: int32 @go(Count) @protobuf(8,varint,opt)

	// Type of this event (Normal, Warning), new types could be added in the future
	// +optional
	type?: string @go(Type) @protobuf(9,bytes,opt)

	// Time when this Event was first observed.
	// +optional
	eventTime?: metav1.#MicroTime @go(EventTime) @protobuf(10,bytes,opt)

	// Data about the Event series this event represents or nil if it's a singleton Event.
	// +optional
	series?: null | #EventSeries @go(Series,*EventSeries) @protobuf(11,bytes,opt)

	// What action was taken/failed regarding to the Regarding object.
	// +optional
	action?: string @go(Action) @protobuf(12,bytes,opt)

	// Optional secondary object for more complex actions.
	// +optional
	related?: null | #ObjectReference @go(Related,*ObjectReference) @protobuf(13,bytes,opt)

	// Name of the controller that emitted this Event, e.g. `kubernetes.io/kubelet`.
	// +optional
	reportingComponent: string @go(ReportingController) @protobuf(14,bytes,opt)

	// ID of the controller instance, e.g. `kubelet-xyzf`.
	// +optional
	reportingInstance: string @go(ReportingInstance) @protobuf(15,bytes,opt)
}

// EventSeries contain information on series of events, i.e. thing that was/is happening
// continuously for some time.
#EventSeries: {
	// Number of occurrences in this series up to the last heartbeat time
	count?: int32 @go(Count) @protobuf(1,varint)

	// Time of the last occurrence observed
	lastObservedTime?: metav1.#MicroTime @go(LastObservedTime) @protobuf(2,bytes)
}

// EventList is a list of events.
#EventList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of events
	items: [...#Event] @go(Items,[]Event) @protobuf(2,bytes,rep)
}

// List holds a list of objects, which may not be known by the server.
#List: metav1.#List

// LimitType is a type of object that is limited
// +enum
#LimitType: string // #enumLimitType

#enumLimitType:
	#LimitTypePod |
	#LimitTypeContainer |
	#LimitTypePersistentVolumeClaim

// Limit that applies to all pods in a namespace
#LimitTypePod: #LimitType & "Pod"

// Limit that applies to all containers in a namespace
#LimitTypeContainer: #LimitType & "Container"

// Limit that applies to all persistent volume claims in a namespace
#LimitTypePersistentVolumeClaim: #LimitType & "PersistentVolumeClaim"

// LimitRangeItem defines a min/max usage limit for any resource that matches on kind.
#LimitRangeItem: {
	// Type of resource that this limit applies to.
	type: #LimitType @go(Type) @protobuf(1,bytes,opt,casttype=LimitType)

	// Max usage constraints on this kind by resource name.
	// +optional
	max?: #ResourceList @go(Max) @protobuf(2,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// Min usage constraints on this kind by resource name.
	// +optional
	min?: #ResourceList @go(Min) @protobuf(3,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// Default resource requirement limit value by resource name if resource limit is omitted.
	// +optional
	default?: #ResourceList @go(Default) @protobuf(4,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// DefaultRequest is the default resource requirement request value by resource name if resource request is omitted.
	// +optional
	defaultRequest?: #ResourceList @go(DefaultRequest) @protobuf(5,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// 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.
	// +optional
	maxLimitRequestRatio?: #ResourceList @go(MaxLimitRequestRatio) @protobuf(6,bytes,rep,casttype=ResourceList,castkey=ResourceName)
}

// LimitRangeSpec defines a min/max usage limit for resources that match on kind.
#LimitRangeSpec: {
	// Limits is the list of LimitRangeItem objects that are enforced.
	limits: [...#LimitRangeItem] @go(Limits,[]LimitRangeItem) @protobuf(1,bytes,rep)
}

// LimitRange sets resource usage limits for each kind of resource in a Namespace.
#LimitRange: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Spec defines the limits enforced.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	spec?: #LimitRangeSpec @go(Spec) @protobuf(2,bytes,opt)
}

// LimitRangeList is a list of LimitRange items.
#LimitRangeList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// Items is a list of LimitRange objects.
	// More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
	items: [...#LimitRange] @go(Items,[]LimitRange) @protobuf(2,bytes,rep)
}

// Pods, number
#ResourcePods: #ResourceName & "pods"

// Services, number
#ResourceServices: #ResourceName & "services"

// ReplicationControllers, number
#ResourceReplicationControllers: #ResourceName & "replicationcontrollers"

// ResourceQuotas, number
#ResourceQuotas: #ResourceName & "resourcequotas"

// ResourceSecrets, number
#ResourceSecrets: #ResourceName & "secrets"

// ResourceConfigMaps, number
#ResourceConfigMaps: #ResourceName & "configmaps"

// ResourcePersistentVolumeClaims, number
#ResourcePersistentVolumeClaims: #ResourceName & "persistentvolumeclaims"

// ResourceServicesNodePorts, number
#ResourceServicesNodePorts: #ResourceName & "services.nodeports"

// ResourceServicesLoadBalancers, number
#ResourceServicesLoadBalancers: #ResourceName & "services.loadbalancers"

// CPU request, in cores. (500m = .5 cores)
#ResourceRequestsCPU: #ResourceName & "requests.cpu"

// Memory request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
#ResourceRequestsMemory: #ResourceName & "requests.memory"

// Storage request, in bytes
#ResourceRequestsStorage: #ResourceName & "requests.storage"

// Local ephemeral storage request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
#ResourceRequestsEphemeralStorage: #ResourceName & "requests.ephemeral-storage"

// CPU limit, in cores. (500m = .5 cores)
#ResourceLimitsCPU: #ResourceName & "limits.cpu"

// Memory limit, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
#ResourceLimitsMemory: #ResourceName & "limits.memory"

// Local ephemeral storage limit, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
#ResourceLimitsEphemeralStorage: #ResourceName & "limits.ephemeral-storage"

// HugePages request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
// As burst is not supported for HugePages, we would only quota its request, and ignore the limit.
#ResourceRequestsHugePagesPrefix: "requests.hugepages-"

// Default resource requests prefix
#DefaultResourceRequestsPrefix: "requests."

// A ResourceQuotaScope defines a filter that must match each object tracked by a quota
// +enum
#ResourceQuotaScope: string // #enumResourceQuotaScope

#enumResourceQuotaScope:
	#ResourceQuotaScopeTerminating |
	#ResourceQuotaScopeNotTerminating |
	#ResourceQuotaScopeBestEffort |
	#ResourceQuotaScopeNotBestEffort |
	#ResourceQuotaScopePriorityClass |
	#ResourceQuotaScopeCrossNamespacePodAffinity

// Match all pod objects where spec.activeDeadlineSeconds >=0
#ResourceQuotaScopeTerminating: #ResourceQuotaScope & "Terminating"

// Match all pod objects where spec.activeDeadlineSeconds is nil
#ResourceQuotaScopeNotTerminating: #ResourceQuotaScope & "NotTerminating"

// Match all pod objects that have best effort quality of service
#ResourceQuotaScopeBestEffort: #ResourceQuotaScope & "BestEffort"

// Match all pod objects that do not have best effort quality of service
#ResourceQuotaScopeNotBestEffort: #ResourceQuotaScope & "NotBestEffort"

// Match all pod objects that have priority class mentioned
#ResourceQuotaScopePriorityClass: #ResourceQuotaScope & "PriorityClass"

// Match all pod objects that have cross-namespace pod (anti)affinity mentioned.
// This is a beta feature enabled by the PodAffinityNamespaceSelector feature flag.
#ResourceQuotaScopeCrossNamespacePodAffinity: #ResourceQuotaScope & "CrossNamespacePodAffinity"

// ResourceQuotaSpec defines the desired hard limits to enforce for Quota.
#ResourceQuotaSpec: {
	// hard is the set of desired hard limits for each named resource.
	// More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
	// +optional
	hard?: #ResourceList @go(Hard) @protobuf(1,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// A collection of filters that must match each object tracked by a quota.
	// If not specified, the quota matches all objects.
	// +optional
	scopes?: [...#ResourceQuotaScope] @go(Scopes,[]ResourceQuotaScope) @protobuf(2,bytes,rep,casttype=ResourceQuotaScope)

	// 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.
	// +optional
	scopeSelector?: null | #ScopeSelector @go(ScopeSelector,*ScopeSelector) @protobuf(3,bytes,opt)
}

// A scope selector represents the AND of the selectors represented
// by the scoped-resource selector requirements.
// +structType=atomic
#ScopeSelector: {
	// A list of scope selector requirements by scope of the resources.
	// +optional
	matchExpressions?: [...#ScopedResourceSelectorRequirement] @go(MatchExpressions,[]ScopedResourceSelectorRequirement) @protobuf(1,bytes,rep)
}

// A scoped-resource selector requirement is a selector that contains values, a scope name, and an operator
// that relates the scope name and values.
#ScopedResourceSelectorRequirement: {
	// The name of the scope that the selector applies to.
	scopeName: #ResourceQuotaScope @go(ScopeName) @protobuf(1,bytes,opt)

	// Represents a scope's relationship to a set of values.
	// Valid operators are In, NotIn, Exists, DoesNotExist.
	operator: #ScopeSelectorOperator @go(Operator) @protobuf(2,bytes,opt,casttype=ScopedResourceSelectorOperator)

	// 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.
	// +optional
	values?: [...string] @go(Values,[]string) @protobuf(3,bytes,rep)
}

// A scope selector operator is the set of operators that can be used in
// a scope selector requirement.
// +enum
#ScopeSelectorOperator: string // #enumScopeSelectorOperator

#enumScopeSelectorOperator:
	#ScopeSelectorOpIn |
	#ScopeSelectorOpNotIn |
	#ScopeSelectorOpExists |
	#ScopeSelectorOpDoesNotExist

#ScopeSelectorOpIn:           #ScopeSelectorOperator & "In"
#ScopeSelectorOpNotIn:        #ScopeSelectorOperator & "NotIn"
#ScopeSelectorOpExists:       #ScopeSelectorOperator & "Exists"
#ScopeSelectorOpDoesNotExist: #ScopeSelectorOperator & "DoesNotExist"

// ResourceQuotaStatus defines the enforced hard limits and observed use.
#ResourceQuotaStatus: {
	// Hard is the set of enforced hard limits for each named resource.
	// More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
	// +optional
	hard?: #ResourceList @go(Hard) @protobuf(1,bytes,rep,casttype=ResourceList,castkey=ResourceName)

	// Used is the current observed total usage of the resource in the namespace.
	// +optional
	used?: #ResourceList @go(Used) @protobuf(2,bytes,rep,casttype=ResourceList,castkey=ResourceName)
}

// ResourceQuota sets aggregate quota restrictions enforced per namespace
#ResourceQuota: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Spec defines the desired quota.
	// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	spec?: #ResourceQuotaSpec @go(Spec) @protobuf(2,bytes,opt)

	// Status defines the actual enforced quota and its current usage.
	// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
	// +optional
	status?: #ResourceQuotaStatus @go(Status) @protobuf(3,bytes,opt)
}

// ResourceQuotaList is a list of ResourceQuota items.
#ResourceQuotaList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// Items is a list of ResourceQuota objects.
	// More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
	items: [...#ResourceQuota] @go(Items,[]ResourceQuota) @protobuf(2,bytes,rep)
}

// Secret holds secret data of a certain type. The total bytes of the values in
// the Data field must be less than MaxSecretSize bytes.
#Secret: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	immutable?: null | bool @go(Immutable,*bool) @protobuf(5,varint,opt)

	// 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
	// +optional
	data?: {[string]: bytes} @go(Data,map[string][]byte) @protobuf(2,bytes,rep)

	// 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.
	// +k8s:conversion-gen=false
	// +optional
	stringData?: {[string]: string} @go(StringData,map[string]string) @protobuf(4,bytes,rep)

	// Used to facilitate programmatic handling of secret data.
	// More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types
	// +optional
	type?: #SecretType @go(Type) @protobuf(3,bytes,opt,casttype=SecretType)
}

#MaxSecretSize: 1048576

#SecretType: string // #enumSecretType

#enumSecretType:
	#SecretTypeOpaque |
	#SecretTypeServiceAccountToken |
	#SecretTypeDockercfg |
	#SecretTypeDockerConfigJson |
	#SecretTypeBasicAuth |
	#SecretTypeSSHAuth |
	#SecretTypeTLS |
	#SecretTypeBootstrapToken

// SecretTypeOpaque is the default. Arbitrary user-defined data
#SecretTypeOpaque: #SecretType & "Opaque"

// SecretTypeServiceAccountToken contains a token that identifies a service account to the API
//
// Required fields:
// - Secret.Annotations["kubernetes.io/service-account.name"] - the name of the ServiceAccount the token identifies
// - Secret.Annotations["kubernetes.io/service-account.uid"] - the UID of the ServiceAccount the token identifies
// - Secret.Data["token"] - a token that identifies the service account to the API
#SecretTypeServiceAccountToken: #SecretType & "kubernetes.io/service-account-token"

// ServiceAccountNameKey is the key of the required annotation for SecretTypeServiceAccountToken secrets
#ServiceAccountNameKey: "kubernetes.io/service-account.name"

// ServiceAccountUIDKey is the key of the required annotation for SecretTypeServiceAccountToken secrets
#ServiceAccountUIDKey: "kubernetes.io/service-account.uid"

// ServiceAccountTokenKey is the key of the required data for SecretTypeServiceAccountToken secrets
#ServiceAccountTokenKey: "token"

// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
#ServiceAccountKubeconfigKey: "kubernetes.kubeconfig"

// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
#ServiceAccountRootCAKey: "ca.crt"

// ServiceAccountNamespaceKey is the key of the optional namespace to use as the default for namespaced API calls
#ServiceAccountNamespaceKey: "namespace"

// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
//
// Required fields:
// - Secret.Data[".dockercfg"] - a serialized ~/.dockercfg file
#SecretTypeDockercfg: #SecretType & "kubernetes.io/dockercfg"

// DockerConfigKey is the key of the required data for SecretTypeDockercfg secrets
#DockerConfigKey: ".dockercfg"

// SecretTypeDockerConfigJson contains a dockercfg file that follows the same format rules as ~/.docker/config.json
//
// Required fields:
// - Secret.Data[".dockerconfigjson"] - a serialized ~/.docker/config.json file
#SecretTypeDockerConfigJson: #SecretType & "kubernetes.io/dockerconfigjson"

// DockerConfigJsonKey is the key of the required data for SecretTypeDockerConfigJson secrets
#DockerConfigJsonKey: ".dockerconfigjson"

// SecretTypeBasicAuth contains data needed for basic authentication.
//
// Required at least one of fields:
// - Secret.Data["username"] - username used for authentication
// - Secret.Data["password"] - password or token needed for authentication
#SecretTypeBasicAuth: #SecretType & "kubernetes.io/basic-auth"

// BasicAuthUsernameKey is the key of the username for SecretTypeBasicAuth secrets
#BasicAuthUsernameKey: "username"

// BasicAuthPasswordKey is the key of the password or token for SecretTypeBasicAuth secrets
#BasicAuthPasswordKey: "password"

// SecretTypeSSHAuth contains data needed for SSH authetication.
//
// Required field:
// - Secret.Data["ssh-privatekey"] - private SSH key needed for authentication
#SecretTypeSSHAuth: #SecretType & "kubernetes.io/ssh-auth"

// SSHAuthPrivateKey is the key of the required SSH private key for SecretTypeSSHAuth secrets
#SSHAuthPrivateKey: "ssh-privatekey"

// SecretTypeTLS contains information about a TLS client or server secret. It
// is primarily used with TLS termination of the Ingress resource, but may be
// used in other types.
//
// Required fields:
// - Secret.Data["tls.key"] - TLS private key.
//   Secret.Data["tls.crt"] - TLS certificate.
// TODO: Consider supporting different formats, specifying CA/destinationCA.
#SecretTypeTLS: #SecretType & "kubernetes.io/tls"

// TLSCertKey is the key for tls certificates in a TLS secret.
#TLSCertKey: "tls.crt"

// TLSPrivateKeyKey is the key for the private key field in a TLS secret.
#TLSPrivateKeyKey: "tls.key"

// SecretTypeBootstrapToken is used during the automated bootstrap process (first
// implemented by kubeadm). It stores tokens that are used to sign well known
// ConfigMaps. They are used for authn.
#SecretTypeBootstrapToken: #SecretType & "bootstrap.kubernetes.io/token"

// SecretList is a list of Secret.
#SecretList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// Items is a list of secret objects.
	// More info: https://kubernetes.io/docs/concepts/configuration/secret
	items: [...#Secret] @go(Items,[]Secret) @protobuf(2,bytes,rep)
}

// ConfigMap holds configuration data for pods to consume.
#ConfigMap: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	immutable?: null | bool @go(Immutable,*bool) @protobuf(4,varint,opt)

	// 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.
	// +optional
	data?: {[string]: string} @go(Data,map[string]string) @protobuf(2,bytes,rep)

	// 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.
	// +optional
	binaryData?: {[string]: bytes} @go(BinaryData,map[string][]byte) @protobuf(3,bytes,rep)
}

// ConfigMapList is a resource containing a list of ConfigMap objects.
#ConfigMapList: {
	metav1.#TypeMeta

	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// Items is the list of ConfigMaps.
	items: [...#ConfigMap] @go(Items,[]ConfigMap) @protobuf(2,bytes,rep)
}

// Type and constants for component health validation.
#ComponentConditionType: string // #enumComponentConditionType

#enumComponentConditionType:
	#ComponentHealthy

#ComponentHealthy: #ComponentConditionType & "Healthy"

// Information about the condition of a component.
#ComponentCondition: {
	// Type of condition for a component.
	// Valid value: "Healthy"
	type: #ComponentConditionType @go(Type) @protobuf(1,bytes,opt,casttype=ComponentConditionType)

	// Status of the condition for a component.
	// Valid values for "Healthy": "True", "False", or "Unknown".
	status: #ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=ConditionStatus)

	// Message about the condition for a component.
	// For example, information about a health check.
	// +optional
	message?: string @go(Message) @protobuf(3,bytes,opt)

	// Condition error code for a component.
	// For example, a health check error code.
	// +optional
	error?: string @go(Error) @protobuf(4,bytes,opt)
}

// ComponentStatus (and ComponentStatusList) holds the cluster validation info.
// Deprecated: This API is deprecated in v1.19+
#ComponentStatus: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// List of component conditions observed
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	conditions?: [...#ComponentCondition] @go(Conditions,[]ComponentCondition) @protobuf(2,bytes,rep)
}

// Status of all the conditions for the component as a list of ComponentStatus objects.
// Deprecated: This API is deprecated in v1.19+
#ComponentStatusList: {
	metav1.#TypeMeta

	// Standard list metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)

	// List of ComponentStatus objects.
	items: [...#ComponentStatus] @go(Items,[]ComponentStatus) @protobuf(2,bytes,rep)
}

// DownwardAPIVolumeSource represents a volume containing downward API info.
// Downward API volumes support ownership management and SELinux relabeling.
#DownwardAPIVolumeSource: {
	// Items is a list of downward API volume file
	// +optional
	items?: [...#DownwardAPIVolumeFile] @go(Items,[]DownwardAPIVolumeFile) @protobuf(1,bytes,rep)

	// 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.
	// +optional
	defaultMode?: null | int32 @go(DefaultMode,*int32) @protobuf(2,varint,opt)
}

#DownwardAPIVolumeSourceDefaultMode: int32 & 0o644

// DownwardAPIVolumeFile represents information to create the file containing the pod field
#DownwardAPIVolumeFile: {
	// 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 '..'
	path: string @go(Path) @protobuf(1,bytes,opt)

	// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
	// +optional
	fieldRef?: null | #ObjectFieldSelector @go(FieldRef,*ObjectFieldSelector) @protobuf(2,bytes,opt)

	// Selects a resource of the container: only resources limits and requests
	// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
	// +optional
	resourceFieldRef?: null | #ResourceFieldSelector @go(ResourceFieldRef,*ResourceFieldSelector) @protobuf(3,bytes,opt)

	// 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.
	// +optional
	mode?: null | int32 @go(Mode,*int32) @protobuf(4,varint,opt)
}

// Represents downward API info for projecting into a projected volume.
// Note that this is identical to a downwardAPI volume source without the default
// mode.
#DownwardAPIProjection: {
	// Items is a list of DownwardAPIVolume file
	// +optional
	items?: [...#DownwardAPIVolumeFile] @go(Items,[]DownwardAPIVolumeFile) @protobuf(1,bytes,rep)
}

// 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.
#SecurityContext: {
	// 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.
	// +optional
	capabilities?: null | #Capabilities @go(Capabilities,*Capabilities) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	privileged?: null | bool @go(Privileged,*bool) @protobuf(2,varint,opt)

	// 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.
	// +optional
	seLinuxOptions?: null | #SELinuxOptions @go(SELinuxOptions,*SELinuxOptions) @protobuf(3,bytes,opt)

	// 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.
	// +optional
	windowsOptions?: null | #WindowsSecurityContextOptions @go(WindowsOptions,*WindowsSecurityContextOptions) @protobuf(10,bytes,opt)

	// 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.
	// +optional
	runAsUser?: null | int64 @go(RunAsUser,*int64) @protobuf(4,varint,opt)

	// 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.
	// +optional
	runAsGroup?: null | int64 @go(RunAsGroup,*int64) @protobuf(8,varint,opt)

	// 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.
	// +optional
	runAsNonRoot?: null | bool @go(RunAsNonRoot,*bool) @protobuf(5,varint,opt)

	// 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.
	// +optional
	readOnlyRootFilesystem?: null | bool @go(ReadOnlyRootFilesystem,*bool) @protobuf(6,varint,opt)

	// 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.
	// +optional
	allowPrivilegeEscalation?: null | bool @go(AllowPrivilegeEscalation,*bool) @protobuf(7,varint,opt)

	// 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.
	// +optional
	procMount?: null | #ProcMountType @go(ProcMount,*ProcMountType) @protobuf(9,bytes,opt)

	// 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.
	// +optional
	seccompProfile?: null | #SeccompProfile @go(SeccompProfile,*SeccompProfile) @protobuf(11,bytes,opt)
}

// +enum
#ProcMountType: string // #enumProcMountType

#enumProcMountType:
	#DefaultProcMount |
	#UnmaskedProcMount

// DefaultProcMount uses the container runtime defaults for readonly and masked
// paths for /proc.  Most container runtimes mask certain paths in /proc to avoid
// accidental security exposure of special devices or information.
#DefaultProcMount: #ProcMountType & "Default"

// UnmaskedProcMount bypasses the default masking behavior of the container
// runtime and ensures the newly created /proc the container stays in tact with
// no modifications.
#UnmaskedProcMount: #ProcMountType & "Unmasked"

// SELinuxOptions are the labels to be applied to the container
#SELinuxOptions: {
	// User is a SELinux user label that applies to the container.
	// +optional
	user?: string @go(User) @protobuf(1,bytes,opt)

	// Role is a SELinux role label that applies to the container.
	// +optional
	role?: string @go(Role) @protobuf(2,bytes,opt)

	// Type is a SELinux type label that applies to the container.
	// +optional
	type?: string @go(Type) @protobuf(3,bytes,opt)

	// Level is SELinux level label that applies to the container.
	// +optional
	level?: string @go(Level) @protobuf(4,bytes,opt)
}

// WindowsSecurityContextOptions contain Windows-specific options and credentials.
#WindowsSecurityContextOptions: {
	// GMSACredentialSpecName is the name of the GMSA credential spec to use.
	// +optional
	gmsaCredentialSpecName?: null | string @go(GMSACredentialSpecName,*string) @protobuf(1,bytes,opt)

	// 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.
	// +optional
	gmsaCredentialSpec?: null | string @go(GMSACredentialSpec,*string) @protobuf(2,bytes,opt)

	// 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.
	// +optional
	runAsUserName?: null | string @go(RunAsUserName,*string) @protobuf(3,bytes,opt)

	// 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.
	// +optional
	hostProcess?: null | bool @go(HostProcess,*bool) @protobuf(4,bytes,opt)
}

// RangeAllocation is not a public type.
#RangeAllocation: {
	metav1.#TypeMeta

	// Standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)

	// Range is string that identifies the range represented by 'data'.
	range: string @go(Range) @protobuf(2,bytes,opt)

	// Data is a bit array containing all allocated addresses in the previous segment.
	data: bytes @go(Data,[]byte) @protobuf(3,bytes,opt)
}

// DefaultSchedulerName defines the name of default scheduler.
#DefaultSchedulerName: "default-scheduler"

// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
// corresponding to every RequiredDuringScheduling affinity rule.
// When the --hard-pod-affinity-weight scheduler flag is not specified,
// DefaultHardPodAffinityWeight defines the weight of the implicit PreferredDuringScheduling affinity rule.
#DefaultHardPodAffinitySymmetricWeight: int32 & 1

// Sysctl defines a kernel parameter to be set
#Sysctl: {
	// Name of a property to set
	name: string @go(Name) @protobuf(1,bytes,opt)

	// Value of a property to set
	value: string @go(Value) @protobuf(2,bytes,opt)
}

// NodeResources is an object for conveying resource information about a node.
// see https://kubernetes.io/docs/concepts/architecture/nodes/#capacity for more details.
#NodeResources: {
	// Capacity represents the available resources of a node
	Capacity: #ResourceList @protobuf(1,bytes,rep,name=capacity,casttype=ResourceList,castkey=ResourceName)
}

// Enable stdin for remote command execution
#ExecStdinParam: "input"

// Enable stdout for remote command execution
#ExecStdoutParam: "output"

// Enable stderr for remote command execution
#ExecStderrParam: "error"

// Enable TTY for remote command execution
#ExecTTYParam: "tty"

// Command to run for remote command execution
#ExecCommandParam: "command"

// Name of header that specifies stream type
#StreamType: "streamType"

// Value for streamType header for stdin stream
#StreamTypeStdin: "stdin"

// Value for streamType header for stdout stream
#StreamTypeStdout: "stdout"

// Value for streamType header for stderr stream
#StreamTypeStderr: "stderr"

// Value for streamType header for data stream
#StreamTypeData: "data"

// Value for streamType header for error stream
#StreamTypeError: "error"

// Value for streamType header for terminal resize stream
#StreamTypeResize: "resize"

// Name of header that specifies the port being forwarded
#PortHeader: "port"

// Name of header that specifies a request ID used to associate the error
// and data streams for a single forwarded connection
#PortForwardRequestIDHeader: "requestID"

#PortStatus: {
	// Port is the port number of the service port of which status is recorded here
	port: int32 @go(Port) @protobuf(1,varint,opt)

	// Protocol is the protocol of the service port of which status is recorded here
	// The supported values are: "TCP", "UDP", "SCTP"
	protocol: #Protocol @go(Protocol) @protobuf(2,bytes,opt,casttype=Protocol)

	// Error is to record the problem with the service port
	// The format of the error shall comply with the following rules:
	// - built-in error values shall be specified in this file and those shall use
	//   CamelCase names
	// - cloud provider specific error values must have names that comply with the
	//   format foo.example.com/CamelCase.
	// ---
	// The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
	// +optional
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$`
	// +kubebuilder:validation:MaxLength=316
	error?: null | string @go(Error,*string) @protobuf(3,bytes,opt)
}
