*: initial update to kube 1.8

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2017-09-26 16:23:09 +02:00
parent 2453222695
commit d6e819133d
No known key found for this signature in database
GPG key ID: B2BEAD150DE936B9
1237 changed files with 84117 additions and 564982 deletions

View file

@ -47,6 +47,8 @@ const (
// CreatedByAnnotation represents the key used to store the spec(json)
// used to create the resource.
// This field is deprecated in favor of ControllerRef (see #44407).
// TODO(#50720): Remove this field in v1.9.
CreatedByAnnotation = "kubernetes.io/created-by"
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
@ -72,11 +74,6 @@ const (
// This annotation can be attached to node.
ObjectTTLAnnotationKey string = "node.alpha.kubernetes.io/ttl"
// AffinityAnnotationKey represents the key of affinity data (json serialized)
// in the Annotations of a Pod.
// TODO: remove when alpha support for affinity is removed
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
// annotation key prefix used to identify non-convertible json paths.
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
@ -94,20 +91,4 @@ const (
//
// Not all cloud providers support this annotation, though AWS & GCE do.
AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges"
// AnnotationValueExternalTrafficLocal Value of annotation to specify local endpoints behavior.
AnnotationValueExternalTrafficLocal = "OnlyLocal"
// AnnotationValueExternalTrafficGlobal Value of annotation to specify global (legacy) behavior.
AnnotationValueExternalTrafficGlobal = "Global"
// TODO: The beta annotations have been deprecated, remove them when we release k8s 1.8.
// BetaAnnotationHealthCheckNodePort Annotation specifying the healthcheck nodePort for the service.
// If not specified, annotation is created by the service api backend with the allocated nodePort.
// Will use user-specified nodePort value if specified by the client.
BetaAnnotationHealthCheckNodePort = "service.beta.kubernetes.io/healthcheck-nodeport"
// BetaAnnotationExternalTraffic An annotation that denotes if this Service desires to route
// external traffic to local endpoints only. This preserves Source IP and avoids a second hop.
BetaAnnotationExternalTraffic = "service.beta.kubernetes.io/external-traffic"
)

View file

@ -31,6 +31,30 @@ import (
"k8s.io/kubernetes/pkg/api"
)
// IsHugePageResourceName returns true if the resource name has the huge page
// resource prefix.
func IsHugePageResourceName(name api.ResourceName) bool {
return strings.HasPrefix(string(name), api.ResourceHugePagesPrefix)
}
// HugePageResourceName returns a ResourceName with the canonical hugepage
// prefix prepended for the specified page size. The page size is converted
// to its canonical representation.
func HugePageResourceName(pageSize resource.Quantity) api.ResourceName {
return api.ResourceName(fmt.Sprintf("%s%s", api.ResourceHugePagesPrefix, pageSize.String()))
}
// HugePageSizeFromResourceName returns the page size for the specified huge page
// resource name. If the specified input is not a valid huge page resource name
// an error is returned.
func HugePageSizeFromResourceName(name api.ResourceName) (resource.Quantity, error) {
if !IsHugePageResourceName(name) {
return resource.Quantity{}, fmt.Errorf("resource name: %s is not valid hugepage name", name)
}
pageSize := strings.TrimPrefix(string(name), api.ResourceHugePagesPrefix)
return resource.ParseQuantity(pageSize)
}
// NonConvertibleFields iterates over the provided map and filters out all but
// any keys with the "non-convertible.kubernetes.io" prefix.
func NonConvertibleFields(annotations map[string]string) map[string]string {
@ -53,6 +77,9 @@ var Semantic = conversion.EqualitiesOrDie(
// Uninitialized quantities are equivalent to 0 quantities.
return a.Cmp(b) == 0
},
func(a, b metav1.MicroTime) bool {
return a.UTC() == b.UTC()
},
func(a, b metav1.Time) bool {
return a.UTC() == b.UTC()
},
@ -104,12 +131,28 @@ func IsResourceQuotaScopeValidForResource(scope api.ResourceQuotaScope, resource
var standardContainerResources = sets.NewString(
string(api.ResourceCPU),
string(api.ResourceMemory),
string(api.ResourceEphemeralStorage),
)
// IsStandardContainerResourceName returns true if the container can make a resource request
// for the specified resource
func IsStandardContainerResourceName(str string) bool {
return standardContainerResources.Has(str)
return standardContainerResources.Has(str) || IsHugePageResourceName(api.ResourceName(str))
}
// IsExtendedResourceName returns true if the resource name is not in the
// default namespace, or it has the opaque integer resource prefix.
func IsExtendedResourceName(name api.ResourceName) bool {
// TODO: Remove OIR part following deprecation.
return !IsDefaultNamespaceResource(name) || IsOpaqueIntResourceName(name)
}
// IsDefaultNamespaceResource returns true if the resource name is in the
// *kubernetes.io/ namespace. Partially-qualified (unprefixed) names are
// implicitly in the kubernetes.io/ namespace.
func IsDefaultNamespaceResource(name api.ResourceName) bool {
return !strings.Contains(string(name), "/") ||
strings.Contains(string(name), api.ResourceDefaultNamespacePrefix)
}
// IsOpaqueIntResourceName returns true if the resource name has the opaque
@ -128,6 +171,16 @@ func OpaqueIntResourceName(name string) api.ResourceName {
return api.ResourceName(fmt.Sprintf("%s%s", api.ResourceOpaqueIntPrefix, name))
}
var overcommitBlacklist = sets.NewString(string(api.ResourceNvidiaGPU))
// IsOvercommitAllowed returns true if the resource is in the default
// namespace and not blacklisted.
func IsOvercommitAllowed(name api.ResourceName) bool {
return IsDefaultNamespaceResource(name) &&
!IsHugePageResourceName(name) &&
!overcommitBlacklist.Has(string(name))
}
var standardLimitRangeTypes = sets.NewString(
string(api.LimitTypePod),
string(api.LimitTypeContainer),
@ -142,11 +195,14 @@ func IsStandardLimitRangeType(str string) bool {
var standardQuotaResources = sets.NewString(
string(api.ResourceCPU),
string(api.ResourceMemory),
string(api.ResourceEphemeralStorage),
string(api.ResourceRequestsCPU),
string(api.ResourceRequestsMemory),
string(api.ResourceRequestsStorage),
string(api.ResourceRequestsEphemeralStorage),
string(api.ResourceLimitsCPU),
string(api.ResourceLimitsMemory),
string(api.ResourceLimitsEphemeralStorage),
string(api.ResourcePods),
string(api.ResourceQuotas),
string(api.ResourceServices),
@ -167,10 +223,13 @@ func IsStandardQuotaResourceName(str string) bool {
var standardResources = sets.NewString(
string(api.ResourceCPU),
string(api.ResourceMemory),
string(api.ResourceEphemeralStorage),
string(api.ResourceRequestsCPU),
string(api.ResourceRequestsMemory),
string(api.ResourceRequestsEphemeralStorage),
string(api.ResourceLimitsCPU),
string(api.ResourceLimitsMemory),
string(api.ResourceLimitsEphemeralStorage),
string(api.ResourcePods),
string(api.ResourceQuotas),
string(api.ResourceServices),
@ -180,11 +239,13 @@ var standardResources = sets.NewString(
string(api.ResourcePersistentVolumeClaims),
string(api.ResourceStorage),
string(api.ResourceRequestsStorage),
string(api.ResourceServicesNodePorts),
string(api.ResourceServicesLoadBalancers),
)
// IsStandardResourceName returns true if the resource is known to the system
func IsStandardResourceName(str string) bool {
return standardResources.Has(str)
return standardResources.Has(str) || IsHugePageResourceName(api.ResourceName(str))
}
var integerResources = sets.NewString(
@ -201,7 +262,7 @@ var integerResources = sets.NewString(
// IsIntegerResourceName returns true if the resource is measured in integer values
func IsIntegerResourceName(str string) bool {
return integerResources.Has(str) || IsOpaqueIntResourceName(api.ResourceName(str))
return integerResources.Has(str) || IsExtendedResourceName(api.ResourceName(str))
}
// this function aims to check if the service's ClusterIP is set or not
@ -519,21 +580,6 @@ func PodAnnotationsFromSysctls(sysctls []api.Sysctl) string {
return strings.Join(kvs, ",")
}
// GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations
// and converts it to the Affinity type in api.
// TODO: remove when alpha support for affinity is removed
func GetAffinityFromPodAnnotations(annotations map[string]string) (*api.Affinity, error) {
if len(annotations) > 0 && annotations[api.AffinityAnnotationKey] != "" {
var affinity api.Affinity
err := json.Unmarshal([]byte(annotations[api.AffinityAnnotationKey]), &affinity)
if err != nil {
return nil, err
}
return &affinity, nil
}
return nil, nil
}
// GetPersistentVolumeClass returns StorageClassName.
func GetPersistentVolumeClass(volume *api.PersistentVolume) string {
// Use beta annotation first

View file

@ -37,7 +37,6 @@ func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *r
&announced.GroupMetaFactoryArgs{
GroupName: api.GroupName,
VersionPreferenceOrder: []string{v1.SchemeGroupVersion.Version},
ImportPrefix: "k8s.io/kubernetes/pkg/api",
AddInternalObjectsToScheme: api.AddToScheme,
RootScopedKinds: sets.NewString(
"Node",

View file

@ -85,6 +85,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&ServiceProxyOptions{},
&NodeList{},
&Node{},
&NodeConfigSource{},
&NodeProxyOptions{},
&Endpoints{},
&EndpointsList{},

View file

@ -54,8 +54,8 @@ func (self *ResourceList) NvidiaGPU() *resource.Quantity {
return &resource.Quantity{}
}
func (self *ResourceList) StorageOverlay() *resource.Quantity {
if val, ok := (*self)[ResourceStorageOverlay]; ok {
func (self *ResourceList) StorageEphemeral() *resource.Quantity {
if val, ok := (*self)[ResourceEphemeralStorage]; ok {
return &val
}
return &resource.Quantity{}

View file

@ -18,13 +18,10 @@ package service
import (
"fmt"
"strconv"
"strings"
"k8s.io/kubernetes/pkg/api"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
"github.com/golang/glog"
)
const (
@ -77,72 +74,13 @@ func RequestsOnlyLocalTraffic(service *api.Service) bool {
return false
}
// First check the beta annotation and then the first class field. This is so that
// existing Services continue to work till the user decides to transition to the
// first class field.
if l, ok := service.Annotations[api.BetaAnnotationExternalTraffic]; ok {
switch l {
case api.AnnotationValueExternalTrafficLocal:
return true
case api.AnnotationValueExternalTrafficGlobal:
return false
default:
glog.Errorf("Invalid value for annotation %v: %v", api.BetaAnnotationExternalTraffic, l)
return false
}
}
return service.Spec.ExternalTrafficPolicy == api.ServiceExternalTrafficPolicyTypeLocal
}
// NeedsHealthCheck Check if service needs health check.
// NeedsHealthCheck checks if service needs health check.
func NeedsHealthCheck(service *api.Service) bool {
if service.Spec.Type != api.ServiceTypeLoadBalancer {
return false
}
return RequestsOnlyLocalTraffic(service)
}
// GetServiceHealthCheckNodePort Return health check node port for service, if one exists
func GetServiceHealthCheckNodePort(service *api.Service) int32 {
// First check the beta annotation and then the first class field. This is so that
// existing Services continue to work till the user decides to transition to the
// first class field.
if l, ok := service.Annotations[api.BetaAnnotationHealthCheckNodePort]; ok {
p, err := strconv.Atoi(l)
if err != nil {
glog.Errorf("Failed to parse annotation %v: %v", api.BetaAnnotationHealthCheckNodePort, err)
return 0
}
return int32(p)
}
return service.Spec.HealthCheckNodePort
}
// ClearExternalTrafficPolicy resets the ExternalTrafficPolicy field.
func ClearExternalTrafficPolicy(service *api.Service) {
// First check the beta annotation and then the first class field. This is so that
// existing Services continue to work till the user decides to transition to the
// first class field.
if _, ok := service.Annotations[api.BetaAnnotationExternalTraffic]; ok {
delete(service.Annotations, api.BetaAnnotationExternalTraffic)
return
}
service.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyType("")
}
// SetServiceHealthCheckNodePort sets the given health check node port on service.
// It does not check whether this service needs healthCheckNodePort.
func SetServiceHealthCheckNodePort(service *api.Service, hcNodePort int32) {
// First check the beta annotation and then the first class field. This is so that
// existing Services continue to work till the user decides to transition to the
// first class field.
if _, ok := service.Annotations[api.BetaAnnotationExternalTraffic]; ok {
if hcNodePort == 0 {
delete(service.Annotations, api.BetaAnnotationHealthCheckNodePort)
} else {
service.Annotations[api.BetaAnnotationHealthCheckNodePort] = fmt.Sprintf("%d", hcNodePort)
}
return
}
service.Spec.HealthCheckNodePort = hcNodePort
}

View file

@ -18,10 +18,10 @@ package api
import (
"k8s.io/apimachinery/pkg/api/resource"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
)
@ -360,7 +360,7 @@ type PersistentVolumeSource struct {
Cinder *CinderVolumeSource
// CephFS represents a Ceph FS mount on the host that shares a pod's lifetime
// +optional
CephFS *CephFSVolumeSource
CephFS *CephFSPersistentVolumeSource
// FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.
// +optional
FC *FCVolumeSource
@ -369,7 +369,7 @@ type PersistentVolumeSource struct {
Flocker *FlockerVolumeSource
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
// +optional
AzureFile *AzureFileVolumeSource
AzureFile *AzureFilePersistentVolumeSource
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
// +optional
VsphereVolume *VsphereVirtualDiskVolumeSource
@ -415,8 +415,9 @@ const (
AlphaStorageNodeAffinityAnnotation = "volume.alpha.kubernetes.io/node-affinity"
)
// +genclient=true
// +nonNamespaced=true
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PersistentVolume struct {
metav1.TypeMeta
@ -454,6 +455,10 @@ type PersistentVolumeSpec struct {
// means that this volume does not belong to any StorageClass.
// +optional
StorageClassName string
// A list of mount options, e.g. ["ro", "soft"]. Not validated - mount will
// simply fail if one is invalid.
// +optional
MountOptions []string
}
// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes
@ -483,6 +488,8 @@ type PersistentVolumeStatus struct {
Reason string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PersistentVolumeList struct {
metav1.TypeMeta
// +optional
@ -490,7 +497,8 @@ type PersistentVolumeList struct {
Items []PersistentVolume
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PersistentVolumeClaim is a user's request for and claim to a persistent volume
type PersistentVolumeClaim struct {
@ -507,6 +515,8 @@ type PersistentVolumeClaim struct {
Status PersistentVolumeClaimStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PersistentVolumeClaimList struct {
metav1.TypeMeta
// +optional
@ -537,6 +547,27 @@ type PersistentVolumeClaimSpec struct {
StorageClassName *string
}
type PersistentVolumeClaimConditionType string
// These are valid conditions of Pvc
const (
// An user trigger resize of pvc has been started
PersistentVolumeClaimResizing PersistentVolumeClaimConditionType = "Resizing"
)
type PersistentVolumeClaimCondition struct {
Type PersistentVolumeClaimConditionType
Status ConditionStatus
// +optional
LastProbeTime metav1.Time
// +optional
LastTransitionTime metav1.Time
// +optional
Reason string
// +optional
Message string
}
type PersistentVolumeClaimStatus struct {
// Phase represents the current phase of PersistentVolumeClaim
// +optional
@ -547,6 +578,8 @@ type PersistentVolumeClaimStatus struct {
// Represents the actual resources of the underlying volume
// +optional
Capacity ResourceList
// +optional
Conditions []PersistentVolumeClaimCondition
}
type PersistentVolumeAccessMode string
@ -591,10 +624,36 @@ const (
ClaimLost PersistentVolumeClaimPhase = "Lost"
)
type HostPathType string
const (
// 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.
type HostPathVolumeSource struct {
// If the path is a symlink, it will follow the link to the real path.
Path string
// Defaults to ""
Type *HostPathType
}
// Represents an empty directory for a pod.
@ -622,8 +681,9 @@ type EmptyDirVolumeSource struct {
type StorageMedium string
const (
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
StorageMediumHugePages StorageMedium = "HugePages" // use hugepages
)
// Protocol defines network protocols supported for things like container ports.
@ -703,15 +763,22 @@ type ISCSIVolumeSource struct {
// The secret is used if either DiscoveryCHAPAuth or SessionCHAPAuth is true
// +optional
SecretRef *LocalObjectReference
// Optional: Custom initiator name per volume.
// If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface
// <target portal>:<volume name> will be created for the connection.
// +optional
InitiatorName *string
}
// 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.
type FCVolumeSource struct {
// Required: FC target worldwide names (WWNs)
// Optional: FC target worldwide names (WWNs)
// +optional
TargetWWNs []string
// Required: FC target lun number
// Optional: FC target lun number
// +optional
Lun *int32
// Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
@ -723,6 +790,10 @@ type FCVolumeSource struct {
// the ReadOnly setting in VolumeMounts.
// +optional
ReadOnly bool
// Optional: FC volume World Wide Identifiers (WWIDs)
// Either WWIDs or TargetWWNs and Lun must be set, but not both simultaneously.
// +optional
WWIDs []string
}
// FlexVolume represents a generic volume resource that is
@ -976,6 +1047,40 @@ type CephFSVolumeSource struct {
ReadOnly bool
}
// SecretReference represents a Secret Reference. It has enough information to retrieve secret
// in any namespace
type SecretReference struct {
// Name is unique within a namespace to reference a secret resource.
// +optional
Name string
// Namespace defines the space within which the secret name must be unique.
// +optional
Namespace string
}
// Represents a Ceph Filesystem mount that lasts the lifetime of a pod
// Cephfs volumes do not support ownership management or SELinux relabeling.
type CephFSPersistentVolumeSource struct {
// Required: Monitors is a collection of Ceph monitors
Monitors []string
// Optional: Used as the mounted root, rather than the full Ceph tree, default is /
// +optional
Path string
// Optional: User is the rados user name, default is admin
// +optional
User string
// Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret
// +optional
SecretFile string
// Optional: SecretRef is reference to the authentication secret for User, default is empty.
// +optional
SecretRef *SecretReference
// Optional: Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
// +optional
ReadOnly bool
}
// 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.
@ -1008,7 +1113,7 @@ type DownwardAPIVolumeSource struct {
type DownwardAPIVolumeFile struct {
// 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
// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
// Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.
// +optional
FieldRef *ObjectFieldSelector
// Selects a resource of the container: only resources limits and requests
@ -1044,6 +1149,22 @@ type AzureFileVolumeSource struct {
ReadOnly bool
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
type AzureFilePersistentVolumeSource struct {
// the name of secret that contains Azure Storage Account Name and Key
SecretName string
// Share Name
ShareName string
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
// +optional
ReadOnly bool
// the namespace of the secret that contains Azure Storage Account Name and Key
// default is the same as the Pod
// +optional
SecretNamespace *string
}
// Represents a vSphere volume resource.
type VsphereVirtualDiskVolumeSource struct {
// Path that identifies vSphere volume vmdk
@ -1348,8 +1469,34 @@ type VolumeMount struct {
// Defaults to "" (volume's root).
// +optional
SubPath string
// mountPropagation determines how mounts are propagated from the host
// to container and the other way around.
// When not set, MountPropagationHostToContainer is used.
// This field is alpha in 1.8 and can be reworked or removed in a future
// release.
// +optional
MountPropagation *MountPropagationMode
}
// MountPropagationMode describes mount propagation.
type MountPropagationMode string
const (
// 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"
)
// EnvVar represents an environment variable present in a Container.
type EnvVar struct {
// Required: This must be a C_IDENTIFIER.
@ -1373,11 +1520,11 @@ type EnvVar struct {
// Only one of its fields may be set.
type EnvVarSource struct {
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
// spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.
// metadata.uid, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.
// +optional
FieldRef *ObjectFieldSelector
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
// (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
// +optional
ResourceFieldRef *ResourceFieldSelector
// Selects a key of a ConfigMap.
@ -1434,7 +1581,7 @@ type SecretKeySelector struct {
// EnvFromSource represents the source of a set of ConfigMaps
type EnvFromSource struct {
// An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
// An optional identifier to prepend to each key in the ConfigMap.
// +optional
Prefix string
// The ConfigMap to select from.
@ -1839,6 +1986,8 @@ const (
RestartPolicyNever RestartPolicy = "Never"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodList is a list of Pods.
type PodList struct {
metav1.TypeMeta
@ -1936,6 +2085,7 @@ type PodAffinity struct {
// podAffinityTerm are intersected, i.e. all terms must be satisfied.
// +optional
// RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm
// If the affinity requirements specified by this field are not met at
// scheduling time, the pod will not be scheduled onto the node.
// If the affinity requirements specified by this field cease to be met
@ -1970,6 +2120,7 @@ type PodAntiAffinity struct {
// podAffinityTerm are intersected, i.e. all terms must be satisfied.
// +optional
// RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm
// If the anti-affinity requirements specified by this field are not met at
// scheduling time, the pod will not be scheduled onto the node.
// If the anti-affinity requirements specified by this field cease to be met
@ -2018,9 +2169,7 @@ type PodAffinityTerm struct {
// 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.
// For PreferredDuringScheduling pod anti-affinity, empty topologyKey is interpreted as "all topologies"
// ("all topologies" here means all the topologyKeys indicated by scheduler command-line argument --failure-domains);
// for affinity and for RequiredDuringScheduling pod anti-affinity, empty topologyKey is not allowed.
// Empty topologyKey is not allowed.
// +optional
TopologyKey string
}
@ -2065,8 +2214,8 @@ type PreferredSchedulingTerm struct {
Preference NodeSelectorTerm
}
// The node this Taint is attached to has the effect "effect" on
// any pod that that does not tolerate the Taint.
// The node this Taint is attached to has the "effect" on
// any pod that does not tolerate the Taint.
type Taint struct {
// Required. The taint key to be applied to a node.
Key string
@ -2100,6 +2249,7 @@ const (
// Kubelet without going through the scheduler to start.
// Enforced by Kubelet and the scheduler.
// TaintEffectNoScheduleNoAdmit TaintEffect = "NoScheduleNoAdmit"
// Evict any already-running pods that do not tolerate the taint.
// Currently enforced by NodeController.
TaintEffectNoExecute TaintEffect = "NoExecute"
@ -2213,6 +2363,20 @@ type PodSpec struct {
// file if specified. This is only valid for non-hostNetwork pods.
// +optional
HostAliases []HostAlias
// If specified, indicates the pod's priority. "SYSTEM" is a special keyword
// which indicates 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
// 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 *int32
}
// HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the
@ -2312,7 +2476,7 @@ type PodStatus struct {
// A human readable message indicating details about why the pod is in this state.
// +optional
Message string
// A brief CamelCase message indicating details about why the pod is in this state. e.g. 'OutOfDisk'
// A brief CamelCase message indicating details about why the pod is in this state. e.g. 'Evicted'
// +optional
Reason string
@ -2342,6 +2506,8 @@ type PodStatus struct {
ContainerStatuses []ContainerStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded
type PodStatusResult struct {
metav1.TypeMeta
@ -2353,7 +2519,8 @@ type PodStatusResult struct {
Status PodStatus
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Pod is a collection of containers, used as either input (create, update) or as output (list, get).
type Pod struct {
@ -2382,7 +2549,8 @@ type PodTemplateSpec struct {
Spec PodSpec
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodTemplate describes a template for creating copies of a predefined pod.
type PodTemplate struct {
@ -2395,6 +2563,8 @@ type PodTemplate struct {
Template PodTemplateSpec
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodTemplateList is a list of PodTemplates.
type PodTemplateList struct {
metav1.TypeMeta
@ -2487,7 +2657,10 @@ type ReplicationControllerCondition struct {
Message string
}
// +genclient=true
// +genclient
// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/extensions.Scale
// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/extensions.Scale,result=k8s.io/kubernetes/pkg/apis/extensions.Scale
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ReplicationController represents the configuration of a replication controller.
type ReplicationController struct {
@ -2505,6 +2678,8 @@ type ReplicationController struct {
Status ReplicationControllerStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ReplicationControllerList is a collection of replication controllers.
type ReplicationControllerList struct {
metav1.TypeMeta
@ -2520,6 +2695,8 @@ const (
ClusterIPNone = "None"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ServiceList holds a list of services.
type ServiceList struct {
metav1.TypeMeta
@ -2540,6 +2717,31 @@ const (
ServiceAffinityNone ServiceAffinity = "None"
)
const (
// DefaultClientIPServiceAffinitySeconds is the default timeout seconds
// of Client IP based session affinity - 3 hours.
DefaultClientIPServiceAffinitySeconds int32 = 10800
// MaxClientIPServiceAffinitySeconds is the max timeout seconds
// of Client IP based session affinity - 1 day.
MaxClientIPServiceAffinitySeconds int32 = 86400
)
// SessionAffinityConfig represents the configurations of session affinity.
type SessionAffinityConfig struct {
// clientIP contains the configurations of Client IP based session affinity.
// +optional
ClientIP *ClientIPConfig
}
// ClientIPConfig represents the configurations of Client IP based session affinity.
type ClientIPConfig struct {
// 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 *int32
}
// Service Type string describes ingress methods for a service
type ServiceType string
@ -2667,6 +2869,10 @@ type ServiceSpec struct {
// +optional
SessionAffinity ServiceAffinity
// sessionAffinityConfig contains the configurations of session affinity.
// +optional
SessionAffinityConfig *SessionAffinityConfig
// Optional: 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."
@ -2689,6 +2895,18 @@ type ServiceSpec struct {
// and ExternalTrafficPolicy is set to Local.
// +optional
HealthCheckNodePort int32
// publishNotReadyAddresses, when set to true, indicates that DNS implementations
// must publish the notReadyAddresses of subsets for the Endpoints associated with
// the Service. The default value is false.
// The primary use case for setting this field is to use a StatefulSet's Headless Service
// to propagate SRV records for its Pods without respect to their readiness for purpose
// of peer discovery.
// This field will replace the service.alpha.kubernetes.io/tolerate-unready-endpoints
// when that annotation is deprecated and all clients have been converted to use this
// field.
// +optional
PublishNotReadyAddresses bool
}
type ServicePort struct {
@ -2717,7 +2935,8 @@ type ServicePort struct {
NodePort int32
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// 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
@ -2736,7 +2955,8 @@ type Service struct {
Status ServiceStatus
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ServiceAccount binds together:
// * a name, understood by users, and perhaps by peripheral systems, for an identity
@ -2762,6 +2982,8 @@ type ServiceAccount struct {
AutomountServiceAccountToken *bool
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ServiceAccountList is a list of ServiceAccount objects
type ServiceAccountList struct {
metav1.TypeMeta
@ -2771,7 +2993,8 @@ type ServiceAccountList struct {
Items []ServiceAccount
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Endpoints is a collection of endpoints that implement the actual service. Example:
// Name: "mysvc",
@ -2841,6 +3064,8 @@ type EndpointPort struct {
Protocol Protocol
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// EndpointsList is a list of endpoints.
type EndpointsList struct {
metav1.TypeMeta
@ -2873,6 +3098,19 @@ type NodeSpec struct {
// If specified, the node's taints.
// +optional
Taints []Taint
// If specified, the source to get node configuration from
// The DynamicKubeletConfig feature gate must be enabled for the Kubelet to use this field
// +optional
ConfigSource *NodeConfigSource
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeConfigSource specifies a source of node configuration. Exactly one subfield must be non-nil.
type NodeConfigSource struct {
metav1.TypeMeta
ConfigMapRef *ObjectReference
}
// DaemonEndpoint contains information about a single Daemon endpoint.
@ -3038,6 +3276,8 @@ const (
NodeDiskPressure NodeConditionType = "DiskPressure"
// NodeNetworkUnavailable means that network for the node is not correctly configured.
NodeNetworkUnavailable NodeConditionType = "NetworkUnavailable"
// NodeConfigOK indicates whether the kubelet is correctly configured
NodeConfigOK NodeConditionType = "ConfigOK"
)
type NodeCondition struct {
@ -3091,27 +3331,28 @@ const (
ResourceMemory ResourceName = "memory"
// Volume size, in bytes (e,g. 5Gi = 5GiB = 5 * 1024 * 1024 * 1024)
ResourceStorage ResourceName = "storage"
// Local Storage for overlay filesystem, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
// The resource name for ResourceStorageOverlay is alpha and it can change across releases.
ResourceStorageOverlay ResourceName = "storage.kubernetes.io/overlay"
// Local Storage for scratch space, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
// The resource name for ResourceStorageScratch is alpha and it can change across releases.
ResourceStorageScratch ResourceName = "storage.kubernetes.io/scratch"
// 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"
// NVIDIA GPU, in devices. Alpha, might change: although fractional and allowing values >1, only one whole device per node is assigned.
ResourceNvidiaGPU ResourceName = "alpha.kubernetes.io/nvidia-gpu"
// Number of Pods that may be running on this Node: see ResourcePods
)
const (
// Namespace prefix for opaque counted resources (alpha).
ResourceOpaqueIntPrefix = "pod.alpha.kubernetes.io/opaque-int-resource-"
// Default namespace prefix.
ResourceDefaultNamespacePrefix = "kubernetes.io/"
// Name prefix for huge page resources (alpha).
ResourceHugePagesPrefix = "hugepages-"
)
// ResourceList is a set of (resource name, quantity) pairs.
type ResourceList map[ResourceName]resource.Quantity
// +genclient=true
// +nonNamespaced=true
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Node is a worker node in Kubernetes
// The name of the node according to etcd is in ObjectMeta.Name.
@ -3129,6 +3370,8 @@ type Node struct {
Status NodeStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeList is a list of nodes.
type NodeList struct {
metav1.TypeMeta
@ -3170,8 +3413,9 @@ const (
NamespaceTerminating NamespacePhase = "Terminating"
)
// +genclient=true
// +nonNamespaced=true
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// A namespace provides a scope for Names.
// Use of multiple namespaces is optional
@ -3189,6 +3433,8 @@ type Namespace struct {
Status NamespaceStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NamespaceList is a list of Namespaces.
type NamespaceList struct {
metav1.TypeMeta
@ -3198,6 +3444,8 @@ type NamespaceList struct {
Items []Namespace
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// 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.
type Binding struct {
@ -3231,6 +3479,8 @@ const (
DeletePropagationForeground DeletionPropagation = "Foreground"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// DeleteOptions may be provided when deleting an API object
// DEPRECATED: This type has been moved to meta/v1 and will be removed soon.
type DeleteOptions struct {
@ -3262,6 +3512,8 @@ type DeleteOptions struct {
PropagationPolicy *DeletionPropagation
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ListOptions is the query options to a standard REST list call, and has future support for
// watch calls.
// DEPRECATED: This type has been moved to meta/v1 and will be removed soon.
@ -3289,6 +3541,8 @@ type ListOptions struct {
TimeoutSeconds *int64
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodLogOptions is the query options for a Pod's logs REST call
type PodLogOptions struct {
metav1.TypeMeta
@ -3321,6 +3575,8 @@ type PodLogOptions struct {
LimitBytes *int64
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodAttachOptions is the query options to a Pod's remote attach call
// TODO: merge w/ PodExecOptions below for stdin, stdout, etc
type PodAttachOptions struct {
@ -3347,6 +3603,8 @@ type PodAttachOptions struct {
Container string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodExecOptions is the query options to a Pod's remote exec call
type PodExecOptions struct {
metav1.TypeMeta
@ -3370,6 +3628,8 @@ type PodExecOptions struct {
Command []string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodPortForwardOptions is the query options to a Pod's port forward call
type PodPortForwardOptions struct {
metav1.TypeMeta
@ -3379,6 +3639,8 @@ type PodPortForwardOptions struct {
Ports []int32
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodProxyOptions is the query options to a Pod's proxy call
type PodProxyOptions struct {
metav1.TypeMeta
@ -3387,6 +3649,8 @@ type PodProxyOptions struct {
Path string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeProxyOptions is the query options to a Node's proxy call
type NodeProxyOptions struct {
metav1.TypeMeta
@ -3395,6 +3659,8 @@ type NodeProxyOptions struct {
Path string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ServiceProxyOptions is the query options to a Service's proxy call.
type ServiceProxyOptions struct {
metav1.TypeMeta
@ -3408,6 +3674,7 @@ type ServiceProxyOptions struct {
}
// ObjectReference contains enough information to let you inspect or modify the referred object.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ObjectReference struct {
// +optional
Kind string
@ -3440,6 +3707,8 @@ type LocalObjectReference struct {
Name string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type SerializedReference struct {
metav1.TypeMeta
// +optional
@ -3463,7 +3732,8 @@ const (
EventTypeWarning string = "Warning"
)
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Event is a report of an event somewhere in the cluster.
// TODO: Decide whether to store these separately or with the object they apply to.
@ -3509,6 +3779,8 @@ type Event struct {
Type string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// EventList is a list of events.
type EventList struct {
metav1.TypeMeta
@ -3518,14 +3790,10 @@ type EventList struct {
Items []Event
}
// List holds a list of objects, which may not be known by the server.
type List struct {
metav1.TypeMeta
// +optional
metav1.ListMeta
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Items []runtime.Object
}
// List holds a list of objects, which may not be known by the server.
type List metainternalversion.List
// A type of object that is limited
type LimitType string
@ -3567,7 +3835,8 @@ type LimitRangeSpec struct {
Limits []LimitRangeItem
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// LimitRange sets resource usage limits for each kind of resource in a Namespace
type LimitRange struct {
@ -3580,6 +3849,8 @@ type LimitRange struct {
Spec LimitRangeSpec
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// LimitRangeList is a list of LimitRange items.
type LimitRangeList struct {
metav1.TypeMeta
@ -3616,10 +3887,14 @@ const (
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"
)
// A ResourceQuotaScope defines a filter that must match each object tracked by a quota
@ -3657,7 +3932,8 @@ type ResourceQuotaStatus struct {
Used ResourceList
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ResourceQuota sets aggregate quota restrictions enforced per namespace
type ResourceQuota struct {
@ -3674,6 +3950,8 @@ type ResourceQuota struct {
Status ResourceQuotaStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ResourceQuotaList is a list of ResourceQuota items
type ResourceQuotaList struct {
metav1.TypeMeta
@ -3684,7 +3962,8 @@ type ResourceQuotaList struct {
Items []ResourceQuota
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Secret holds secret data of a certain type. The total bytes of the values in
// the Data field must be less than MaxSecretSize bytes.
@ -3787,8 +4066,14 @@ const (
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"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type SecretList struct {
metav1.TypeMeta
// +optional
@ -3797,7 +4082,8 @@ type SecretList struct {
Items []Secret
}
// +genclient=true
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ConfigMap holds configuration data for components or applications to consume.
type ConfigMap struct {
@ -3811,6 +4097,8 @@ type ConfigMap struct {
Data map[string]string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ConfigMapList is a resource containing a list of ConfigMap objects.
type ConfigMapList struct {
metav1.TypeMeta
@ -3838,7 +4126,7 @@ const (
// Enable TTY for remote command execution
ExecTTYParam = "tty"
// Command to run for remote command execution
ExecCommandParamm = "command"
ExecCommandParam = "command"
// Name of header that specifies stream type
StreamType = "streamType"
@ -3879,8 +4167,9 @@ type ComponentCondition struct {
Error string
}
// +genclient=true
// +nonNamespaced=true
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ComponentStatus (and ComponentStatusList) holds the cluster validation info.
type ComponentStatus struct {
@ -3892,6 +4181,8 @@ type ComponentStatus struct {
Conditions []ComponentCondition
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ComponentStatusList struct {
metav1.TypeMeta
// +optional
@ -3937,6 +4228,11 @@ type SecurityContext struct {
// files to, ensuring the persistent data can only be written to mounts.
// +optional
ReadOnlyRootFilesystem *bool
// AllowPrivilegeEscalation controls whether a process can gain more
// privileges than its parent process. This bool directly controls if
// the no_new_privs flag will be set on the container process.
// +optional
AllowPrivilegeEscalation *bool
}
// SELinuxOptions are the labels to be applied to the container.
@ -3955,6 +4251,8 @@ type SELinuxOptions struct {
Level string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// RangeAllocation is an opaque API object (not exposed to end users) that can be persisted to record
// the global allocation state of the cluster. The schema of Range and Data generic, in that Range
// should be a string representation of the inputs to a range (for instance, for IP allocation it

View file

@ -1,113 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file should be consistent with pkg/api/annotation_key_constants.go.
package v1
const (
// ImagePolicyFailedOpenKey is added to pods created by failing open when the image policy
// webhook backend fails.
ImagePolicyFailedOpenKey string = "alpha.image-policy.k8s.io/failed-open"
// PodPresetOptOutAnnotationKey represents the annotation key for a pod to exempt itself from pod preset manipulation
PodPresetOptOutAnnotationKey string = "podpreset.admission.kubernetes.io/exclude"
// MirrorAnnotationKey represents the annotation key set by kubelets when creating mirror pods
MirrorPodAnnotationKey string = "kubernetes.io/config.mirror"
// TolerationsAnnotationKey represents the key of tolerations data (json serialized)
// in the Annotations of a Pod.
TolerationsAnnotationKey string = "scheduler.alpha.kubernetes.io/tolerations"
// TaintsAnnotationKey represents the key of taints data (json serialized)
// in the Annotations of a Node.
TaintsAnnotationKey string = "scheduler.alpha.kubernetes.io/taints"
// SeccompPodAnnotationKey represents the key of a seccomp profile applied
// to all containers of a pod.
SeccompPodAnnotationKey string = "seccomp.security.alpha.kubernetes.io/pod"
// SeccompContainerAnnotationKeyPrefix represents the key of a seccomp profile applied
// to one container of a pod.
SeccompContainerAnnotationKeyPrefix string = "container.seccomp.security.alpha.kubernetes.io/"
// CreatedByAnnotation represents the key used to store the spec(json)
// used to create the resource.
CreatedByAnnotation = "kubernetes.io/created-by"
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
// in the Annotations of a Node.
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
// SysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
// key-value pairs. Only a limited set of whitelisted and isolated sysctls is supported by
// the kubelet. Pods with other sysctls will fail to launch.
SysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
// UnsafeSysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
// key-value pairs. Unsafe sysctls must be explicitly enabled for a kubelet. They are properly
// namespaced to a pod or a container, but their isolation is usually unclear or weak. Their use
// is at-your-own-risk. Pods that attempt to set an unsafe sysctl that is not enabled for a kubelet
// will fail to launch.
UnsafeSysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/unsafe-sysctls"
// ObjectTTLAnnotations represents a suggestion for kubelet for how long it can cache
// an object (e.g. secret, config map) before fetching it again from apiserver.
// This annotation can be attached to node.
ObjectTTLAnnotationKey string = "node.alpha.kubernetes.io/ttl"
// AffinityAnnotationKey represents the key of affinity data (json serialized)
// in the Annotations of a Pod.
// TODO: remove when alpha support for affinity is removed
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
// annotation key prefix used to identify non-convertible json paths.
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
kubectlPrefix = "kubectl.kubernetes.io/"
// LastAppliedConfigAnnotation is the annotation used to store the previous
// configuration of a resource for use in a three way diff by UpdateApplyAnnotation.
LastAppliedConfigAnnotation = kubectlPrefix + "last-applied-configuration"
// AnnotationLoadBalancerSourceRangesKey is the key of the annotation on a service to set allowed ingress ranges on their LoadBalancers
//
// It should be a comma-separated list of CIDRs, e.g. `0.0.0.0/0` to
// allow full access (the default) or `18.0.0.0/8,56.0.0.0/8` to allow
// access only from the CIDRs currently allocated to MIT & the USPS.
//
// Not all cloud providers support this annotation, though AWS & GCE do.
AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges"
// AnnotationValueExternalTrafficLocal Value of annotation to specify local endpoints behavior.
AnnotationValueExternalTrafficLocal = "OnlyLocal"
// AnnotationValueExternalTrafficGlobal Value of annotation to specify global (legacy) behavior.
AnnotationValueExternalTrafficGlobal = "Global"
// TODO: The beta annotations have been deprecated, remove them when we release k8s 1.8.
// BetaAnnotationHealthCheckNodePort Annotation specifying the healthcheck nodePort for the service.
// If not specified, annotation is created by the service api backend with the allocated nodePort.
// Will use user-specified nodePort value if specified by the client.
BetaAnnotationHealthCheckNodePort = "service.beta.kubernetes.io/healthcheck-nodeport"
// BetaAnnotationExternalTraffic An annotation that denotes if this Service desires to route
// external traffic to local endpoints only. This preserves Source IP and avoids a second hop.
BetaAnnotationExternalTraffic = "service.beta.kubernetes.io/external-traffic"
)

View file

@ -17,10 +17,11 @@ limitations under the License.
package v1
import (
"encoding/json"
"fmt"
"reflect"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
@ -35,80 +36,80 @@ import (
func addFastPathConversionFuncs(scheme *runtime.Scheme) error {
scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) {
switch a := objA.(type) {
case *Pod:
case *v1.Pod:
switch b := objB.(type) {
case *api.Pod:
return true, Convert_v1_Pod_To_api_Pod(a, b, s)
}
case *api.Pod:
switch b := objB.(type) {
case *Pod:
case *v1.Pod:
return true, Convert_api_Pod_To_v1_Pod(a, b, s)
}
case *Event:
case *v1.Event:
switch b := objB.(type) {
case *api.Event:
return true, Convert_v1_Event_To_api_Event(a, b, s)
}
case *api.Event:
switch b := objB.(type) {
case *Event:
case *v1.Event:
return true, Convert_api_Event_To_v1_Event(a, b, s)
}
case *ReplicationController:
case *v1.ReplicationController:
switch b := objB.(type) {
case *api.ReplicationController:
return true, Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s)
}
case *api.ReplicationController:
switch b := objB.(type) {
case *ReplicationController:
case *v1.ReplicationController:
return true, Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s)
}
case *Node:
case *v1.Node:
switch b := objB.(type) {
case *api.Node:
return true, Convert_v1_Node_To_api_Node(a, b, s)
}
case *api.Node:
switch b := objB.(type) {
case *Node:
case *v1.Node:
return true, Convert_api_Node_To_v1_Node(a, b, s)
}
case *Namespace:
case *v1.Namespace:
switch b := objB.(type) {
case *api.Namespace:
return true, Convert_v1_Namespace_To_api_Namespace(a, b, s)
}
case *api.Namespace:
switch b := objB.(type) {
case *Namespace:
case *v1.Namespace:
return true, Convert_api_Namespace_To_v1_Namespace(a, b, s)
}
case *Service:
case *v1.Service:
switch b := objB.(type) {
case *api.Service:
return true, Convert_v1_Service_To_api_Service(a, b, s)
}
case *api.Service:
switch b := objB.(type) {
case *Service:
case *v1.Service:
return true, Convert_api_Service_To_v1_Service(a, b, s)
}
case *Endpoints:
case *v1.Endpoints:
switch b := objB.(type) {
case *api.Endpoints:
return true, Convert_v1_Endpoints_To_api_Endpoints(a, b, s)
}
case *api.Endpoints:
switch b := objB.(type) {
case *Endpoints:
case *v1.Endpoints:
return true, Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
}
@ -152,32 +153,6 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
return err
}
// Add field label conversions for kinds having selectable nothing but ObjectMeta fields.
for _, k := range []string{
"Endpoints",
"ResourceQuota",
"PersistentVolumeClaim",
"Service",
"ServiceAccount",
"ConfigMap",
} {
kind := k // don't close over range variables
err = scheme.AddFieldLabelConversionFunc("v1", kind,
func(label, value string) (string, string, error) {
switch label {
case "metadata.namespace",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label %q not supported for %q", label, kind)
}
},
)
if err != nil {
return err
}
}
// Add field conversion funcs.
err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
func(label, value string) (string, string, error) {
@ -186,9 +161,11 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
"metadata.labels",
"metadata.name",
"metadata.namespace",
"metadata.uid",
"spec.nodeName",
"spec.restartPolicy",
"spec.serviceAccountName",
"spec.schedulerName",
"status.phase",
"status.hostIP",
"status.podIP":
@ -233,19 +210,6 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
if err != nil {
return err
}
err = scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
func(label, value string) (string, string, error) {
switch label {
case "metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
},
)
if err != nil {
return err
}
if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
return err
}
@ -258,7 +222,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
return nil
}
func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error {
func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *v1.ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
return err
@ -269,7 +233,7 @@ func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *ReplicationCo
return nil
}
func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
out.Replicas = *in.Replicas
if in.Selector != nil {
metav1.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s)
@ -282,7 +246,7 @@ func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *Repli
return nil
}
func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error {
func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *v1.ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error {
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
@ -291,7 +255,7 @@ func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *R
return nil
}
func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *ReplicationController, s conversion.Scope) error {
func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *v1.ReplicationController, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil {
fieldErr, ok := err.(*field.Error)
@ -301,7 +265,7 @@ func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.Re
if out.Annotations == nil {
out.Annotations = make(map[string]string)
}
out.Annotations[NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
out.Annotations[v1.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
}
if err := Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil {
return err
@ -309,7 +273,7 @@ func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.Re
return nil
}
func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
out.Replicas = new(int32)
*out.Replicas = in.Replicas
out.MinReadySeconds = in.MinReadySeconds
@ -317,14 +281,14 @@ func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *exten
if in.Selector != nil {
invalidErr = metav1.Convert_unversioned_LabelSelector_to_map(in.Selector, &out.Selector, s)
}
out.Template = new(PodTemplateSpec)
out.Template = new(v1.PodTemplateSpec)
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil {
return err
}
return invalidErr
}
func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *ReplicationControllerStatus, s conversion.Scope) error {
func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *v1.ReplicationControllerStatus, s conversion.Scope) error {
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
@ -333,12 +297,12 @@ func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *e
return nil
}
func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
out.Replicas = &in.Replicas
out.MinReadySeconds = in.MinReadySeconds
out.Selector = in.Selector
if in.Template != nil {
out.Template = new(PodTemplateSpec)
out.Template = new(v1.PodTemplateSpec)
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
return err
}
@ -348,7 +312,7 @@ func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *a
return nil
}
func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *v1.ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
if in.Replicas != nil {
out.Replicas = *in.Replicas
}
@ -365,152 +329,25 @@ func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *R
return nil
}
func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error {
if err := autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s); err != nil {
return err
}
if old := out.Annotations; old != nil {
out.Annotations = make(map[string]string, len(old))
for k, v := range old {
out.Annotations[k] = v
}
}
if len(out.Status.InitContainerStatuses) > 0 {
if out.Annotations == nil {
out.Annotations = make(map[string]string)
}
value, err := json.Marshal(out.Status.InitContainerStatuses)
if err != nil {
return err
}
out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value)
out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value)
} else {
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
return nil
}
func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error {
// TODO: sometime after we move init container to stable, remove these conversions
// If there is a beta annotation, copy to alpha key.
// See commit log for PR #31026 for why we do this.
if valueBeta, okBeta := in.Annotations[PodInitContainerStatusesBetaAnnotationKey]; okBeta {
in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta
}
// Move the annotation to the internal repr. field
if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
var values []ContainerStatus
if err := json.Unmarshal([]byte(value), &values); err != nil {
return err
}
// Conversion from external to internal version exists more to
// satisfy the needs of the decoder than it does to be a general
// purpose tool. And Decode always creates an intermediate object
// to decode to. Thus the caller of UnsafeConvertToVersion is
// taking responsibility to ensure mutation of in is not exposed
// back to the caller.
in.Status.InitContainerStatuses = values
}
if err := autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s); err != nil {
return err
}
if len(out.Annotations) > 0 {
old := out.Annotations
out.Annotations = make(map[string]string, len(old))
for k, v := range old {
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
return nil
}
func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error {
func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error {
if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil {
return err
}
// TODO: sometime after we move init container to stable, remove these conversions.
if old := out.Annotations; old != nil {
out.Annotations = make(map[string]string, len(old))
for k, v := range old {
out.Annotations[k] = v
}
}
if len(out.Spec.InitContainers) > 0 {
if out.Annotations == nil {
out.Annotations = make(map[string]string)
}
value, err := json.Marshal(out.Spec.InitContainers)
if err != nil {
return err
}
out.Annotations[PodInitContainersAnnotationKey] = string(value)
out.Annotations[PodInitContainersBetaAnnotationKey] = string(value)
} else {
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
}
return nil
}
func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error {
// TODO: sometime after we move init container to stable, remove these conversions
// If there is a beta annotation, copy to alpha key.
// See commit log for PR #31026 for why we do this.
if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta {
in.Annotations[PodInitContainersAnnotationKey] = valueBeta
}
// Move the annotation to the internal repr. field
if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok {
var values []Container
if err := json.Unmarshal([]byte(value), &values); err != nil {
return err
}
// Conversion from external to internal version exists more to
// satisfy the needs of the decoder than it does to be a general
// purpose tool. And Decode always creates an intermediate object
// to decode to. Thus the caller of UnsafeConvertToVersion is
// taking responsibility to ensure mutation of in is not exposed
// back to the caller.
in.Spec.InitContainers = values
// Call defaulters explicitly until annotations are removed
tmpPodTemp := &PodTemplate{
Template: PodTemplateSpec{
Spec: PodSpec{
HostNetwork: in.Spec.HostNetwork,
InitContainers: values,
},
},
}
SetObjectDefaults_PodTemplate(tmpPodTemp)
in.Spec.InitContainers = tmpPodTemp.Template.Spec.InitContainers
}
func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error {
if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil {
return err
}
if len(out.Annotations) > 0 {
old := out.Annotations
out.Annotations = make(map[string]string, len(old))
for k, v := range old {
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
}
return nil
}
// The following two PodSpec conversions are done here to support ServiceAccount
// The following two v1.PodSpec conversions are done here to support v1.ServiceAccount
// as an alias for ServiceAccountName.
func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error {
func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s conversion.Scope) error {
if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil {
return err
}
@ -529,7 +366,7 @@ func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversi
return nil
}
func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error {
func Convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conversion.Scope) error {
if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil {
return err
}
@ -552,110 +389,29 @@ func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi
return nil
}
func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error {
func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *v1.Pod, s conversion.Scope) error {
if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil {
return err
}
// TODO: sometime after we move init container to stable, remove these conversions
if len(out.Spec.InitContainers) > 0 || len(out.Status.InitContainerStatuses) > 0 {
old := out.Annotations
out.Annotations = make(map[string]string, len(old))
for k, v := range old {
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
if len(out.Spec.InitContainers) > 0 {
value, err := json.Marshal(out.Spec.InitContainers)
if err != nil {
return err
}
out.Annotations[PodInitContainersAnnotationKey] = string(value)
out.Annotations[PodInitContainersBetaAnnotationKey] = string(value)
}
if len(out.Status.InitContainerStatuses) > 0 {
value, err := json.Marshal(out.Status.InitContainerStatuses)
if err != nil {
return err
}
out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value)
out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value)
}
return nil
}
func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error {
// If there is a beta annotation, copy to alpha key.
// See commit log for PR #31026 for why we do this.
if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta {
in.Annotations[PodInitContainersAnnotationKey] = valueBeta
}
// TODO: sometime after we move init container to stable, remove these conversions
// Move the annotation to the internal repr. field
if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok {
var values []Container
if err := json.Unmarshal([]byte(value), &values); err != nil {
return err
}
// Conversion from external to internal version exists more to
// satisfy the needs of the decoder than it does to be a general
// purpose tool. And Decode always creates an intermediate object
// to decode to. Thus the caller of UnsafeConvertToVersion is
// taking responsibility to ensure mutation of in is not exposed
// back to the caller.
in.Spec.InitContainers = values
// Call defaulters explicitly until annotations are removed
tmpPod := &Pod{
Spec: PodSpec{
HostNetwork: in.Spec.HostNetwork,
InitContainers: values,
},
}
SetObjectDefaults_Pod(tmpPod)
in.Spec.InitContainers = tmpPod.Spec.InitContainers
}
// If there is a beta annotation, copy to alpha key.
// See commit log for PR #31026 for why we do this.
if valueBeta, okBeta := in.Annotations[PodInitContainerStatusesBetaAnnotationKey]; okBeta {
in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta
}
if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
var values []ContainerStatus
if err := json.Unmarshal([]byte(value), &values); err != nil {
return err
}
// Conversion from external to internal version exists more to
// satisfy the needs of the decoder than it does to be a general
// purpose tool. And Decode always creates an intermediate object
// to decode to. Thus the caller of UnsafeConvertToVersion is
// taking responsibility to ensure mutation of in is not exposed
// back to the caller.
in.Status.InitContainerStatuses = values
}
if err := autoConvert_v1_Pod_To_api_Pod(in, out, s); err != nil {
return err
}
// drop init container annotations so they don't take effect on legacy kubelets.
// remove this once the oldest supported kubelet no longer honors the annotations over the field.
if len(out.Annotations) > 0 {
old := out.Annotations
out.Annotations = make(map[string]string, len(old))
for k, v := range old {
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
delete(out.Annotations, "pod.beta.kubernetes.io/init-containers")
delete(out.Annotations, "pod.alpha.kubernetes.io/init-containers")
delete(out.Annotations, "pod.beta.kubernetes.io/init-container-statuses")
delete(out.Annotations, "pod.alpha.kubernetes.io/init-container-statuses")
}
return nil
}
func Convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error {
func Convert_v1_Secret_To_api_Secret(in *v1.Secret, out *api.Secret, s conversion.Scope) error {
if err := autoConvert_v1_Secret_To_api_Secret(in, out, s); err != nil {
return err
}
@ -672,11 +428,35 @@ func Convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.S
return nil
}
func Convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error {
if in.Capabilities != nil {
out.Capabilities = new(v1.Capabilities)
if err := Convert_api_Capabilities_To_v1_Capabilities(in.Capabilities, out.Capabilities, s); err != nil {
return err
}
} else {
out.Capabilities = nil
}
out.Privileged = in.Privileged
if in.SELinuxOptions != nil {
out.SELinuxOptions = new(v1.SELinuxOptions)
if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
return err
}
} else {
out.SELinuxOptions = nil
}
out.RunAsUser = in.RunAsUser
out.RunAsNonRoot = in.RunAsNonRoot
out.ReadOnlyRootFilesystem = in.ReadOnlyRootFilesystem
out.AllowPrivilegeEscalation = in.AllowPrivilegeEscalation
return nil
}
func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error {
func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *v1.PodSecurityContext, s conversion.Scope) error {
out.SupplementalGroups = in.SupplementalGroups
if in.SELinuxOptions != nil {
out.SELinuxOptions = new(SELinuxOptions)
out.SELinuxOptions = new(v1.SELinuxOptions)
if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
return err
}
@ -689,7 +469,7 @@ func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurity
return nil
}
func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
out.SupplementalGroups = in.SupplementalGroups
if in.SELinuxOptions != nil {
out.SELinuxOptions = new(api.SELinuxOptions)
@ -706,7 +486,7 @@ func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityCont
}
// +k8s:conversion-fn=copy-only
func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.ResourceList, s conversion.Scope) error {
func Convert_v1_ResourceList_To_api_ResourceList(in *v1.ResourceList, out *api.ResourceList, s conversion.Scope) error {
if *in == nil {
return nil
}

View file

@ -17,36 +17,37 @@ limitations under the License.
package v1
import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/parsers"
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
return RegisterDefaults(scheme)
}
func SetDefaults_ResourceList(obj *ResourceList) {
func SetDefaults_ResourceList(obj *v1.ResourceList) {
for key, val := range *obj {
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
// In the future, we should instead reject values that need rounding.
const milliScale = -3
val.RoundUp(milliScale)
(*obj)[ResourceName(key)] = val
(*obj)[v1.ResourceName(key)] = val
}
}
func SetDefaults_PodExecOptions(obj *PodExecOptions) {
func SetDefaults_PodExecOptions(obj *v1.PodExecOptions) {
obj.Stdout = true
obj.Stderr = true
}
func SetDefaults_PodAttachOptions(obj *PodAttachOptions) {
func SetDefaults_PodAttachOptions(obj *v1.PodAttachOptions) {
obj.Stdout = true
obj.Stderr = true
}
func SetDefaults_ReplicationController(obj *ReplicationController) {
func SetDefaults_ReplicationController(obj *v1.ReplicationController) {
var labels map[string]string
if obj.Spec.Template != nil {
labels = obj.Spec.Template.Labels
@ -65,48 +66,61 @@ func SetDefaults_ReplicationController(obj *ReplicationController) {
*obj.Spec.Replicas = 1
}
}
func SetDefaults_Volume(obj *Volume) {
if util.AllPtrFieldsNil(&obj.VolumeSource) {
obj.VolumeSource = VolumeSource{
EmptyDir: &EmptyDirVolumeSource{},
func SetDefaults_Volume(obj *v1.Volume) {
if utilpointer.AllPtrFieldsNil(&obj.VolumeSource) {
obj.VolumeSource = v1.VolumeSource{
EmptyDir: &v1.EmptyDirVolumeSource{},
}
}
}
func SetDefaults_ContainerPort(obj *ContainerPort) {
func SetDefaults_ContainerPort(obj *v1.ContainerPort) {
if obj.Protocol == "" {
obj.Protocol = ProtocolTCP
obj.Protocol = v1.ProtocolTCP
}
}
func SetDefaults_Container(obj *Container) {
func SetDefaults_Container(obj *v1.Container) {
if obj.ImagePullPolicy == "" {
// Ignore error and assume it has been validated elsewhere
_, tag, _, _ := parsers.ParseImageName(obj.Image)
// Check image tag
if tag == "latest" {
obj.ImagePullPolicy = PullAlways
obj.ImagePullPolicy = v1.PullAlways
} else {
obj.ImagePullPolicy = PullIfNotPresent
obj.ImagePullPolicy = v1.PullIfNotPresent
}
}
if obj.TerminationMessagePath == "" {
obj.TerminationMessagePath = TerminationMessagePathDefault
obj.TerminationMessagePath = v1.TerminationMessagePathDefault
}
if obj.TerminationMessagePolicy == "" {
obj.TerminationMessagePolicy = TerminationMessageReadFile
obj.TerminationMessagePolicy = v1.TerminationMessageReadFile
}
}
func SetDefaults_Service(obj *Service) {
func SetDefaults_Service(obj *v1.Service) {
if obj.Spec.SessionAffinity == "" {
obj.Spec.SessionAffinity = ServiceAffinityNone
obj.Spec.SessionAffinity = v1.ServiceAffinityNone
}
if obj.Spec.SessionAffinity == v1.ServiceAffinityNone {
obj.Spec.SessionAffinityConfig = nil
}
if obj.Spec.SessionAffinity == v1.ServiceAffinityClientIP {
if obj.Spec.SessionAffinityConfig == nil || obj.Spec.SessionAffinityConfig.ClientIP == nil || obj.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds == nil {
timeoutSeconds := v1.DefaultClientIPServiceAffinitySeconds
obj.Spec.SessionAffinityConfig = &v1.SessionAffinityConfig{
ClientIP: &v1.ClientIPConfig{
TimeoutSeconds: &timeoutSeconds,
},
}
}
}
if obj.Spec.Type == "" {
obj.Spec.Type = ServiceTypeClusterIP
obj.Spec.Type = v1.ServiceTypeClusterIP
}
for i := range obj.Spec.Ports {
sp := &obj.Spec.Ports[i]
if sp.Protocol == "" {
sp.Protocol = ProtocolTCP
sp.Protocol = v1.ProtocolTCP
}
if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") {
sp.TargetPort = intstr.FromInt(int(sp.Port))
@ -114,24 +128,21 @@ func SetDefaults_Service(obj *Service) {
}
// Defaults ExternalTrafficPolicy field for NodePort / LoadBalancer service
// to Global for consistency.
if _, ok := obj.Annotations[BetaAnnotationExternalTraffic]; ok {
// Don't default this field if beta annotation exists.
return
} else if (obj.Spec.Type == ServiceTypeNodePort ||
obj.Spec.Type == ServiceTypeLoadBalancer) &&
if (obj.Spec.Type == v1.ServiceTypeNodePort ||
obj.Spec.Type == v1.ServiceTypeLoadBalancer) &&
obj.Spec.ExternalTrafficPolicy == "" {
obj.Spec.ExternalTrafficPolicy = ServiceExternalTrafficPolicyTypeCluster
obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeCluster
}
}
func SetDefaults_Pod(obj *Pod) {
func SetDefaults_Pod(obj *v1.Pod) {
// If limits are specified, but requests are not, default requests to limits
// This is done here rather than a more specific defaulting pass on ResourceRequirements
// because we only want this defaulting semantic to take place on a Pod and not a PodTemplate
// This is done here rather than a more specific defaulting pass on v1.ResourceRequirements
// because we only want this defaulting semantic to take place on a v1.Pod and not a v1.PodTemplate
for i := range obj.Spec.Containers {
// set requests to limits if requests are not specified, but limits are
if obj.Spec.Containers[i].Resources.Limits != nil {
if obj.Spec.Containers[i].Resources.Requests == nil {
obj.Spec.Containers[i].Resources.Requests = make(ResourceList)
obj.Spec.Containers[i].Resources.Requests = make(v1.ResourceList)
}
for key, value := range obj.Spec.Containers[i].Resources.Limits {
if _, exists := obj.Spec.Containers[i].Resources.Requests[key]; !exists {
@ -143,7 +154,7 @@ func SetDefaults_Pod(obj *Pod) {
for i := range obj.Spec.InitContainers {
if obj.Spec.InitContainers[i].Resources.Limits != nil {
if obj.Spec.InitContainers[i].Resources.Requests == nil {
obj.Spec.InitContainers[i].Resources.Requests = make(ResourceList)
obj.Spec.InitContainers[i].Resources.Requests = make(v1.ResourceList)
}
for key, value := range obj.Spec.InitContainers[i].Resources.Limits {
if _, exists := obj.Spec.InitContainers[i].Resources.Requests[key]; !exists {
@ -153,29 +164,29 @@ func SetDefaults_Pod(obj *Pod) {
}
}
}
func SetDefaults_PodSpec(obj *PodSpec) {
func SetDefaults_PodSpec(obj *v1.PodSpec) {
if obj.DNSPolicy == "" {
obj.DNSPolicy = DNSClusterFirst
obj.DNSPolicy = v1.DNSClusterFirst
}
if obj.RestartPolicy == "" {
obj.RestartPolicy = RestartPolicyAlways
obj.RestartPolicy = v1.RestartPolicyAlways
}
if obj.HostNetwork {
defaultHostNetworkPorts(&obj.Containers)
defaultHostNetworkPorts(&obj.InitContainers)
}
if obj.SecurityContext == nil {
obj.SecurityContext = &PodSecurityContext{}
obj.SecurityContext = &v1.PodSecurityContext{}
}
if obj.TerminationGracePeriodSeconds == nil {
period := int64(DefaultTerminationGracePeriodSeconds)
period := int64(v1.DefaultTerminationGracePeriodSeconds)
obj.TerminationGracePeriodSeconds = &period
}
if obj.SchedulerName == "" {
obj.SchedulerName = DefaultSchedulerName
obj.SchedulerName = v1.DefaultSchedulerName
}
}
func SetDefaults_Probe(obj *Probe) {
func SetDefaults_Probe(obj *v1.Probe) {
if obj.TimeoutSeconds == 0 {
obj.TimeoutSeconds = 1
}
@ -189,61 +200,61 @@ func SetDefaults_Probe(obj *Probe) {
obj.FailureThreshold = 3
}
}
func SetDefaults_SecretVolumeSource(obj *SecretVolumeSource) {
func SetDefaults_SecretVolumeSource(obj *v1.SecretVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(SecretVolumeSourceDefaultMode)
perm := int32(v1.SecretVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_ConfigMapVolumeSource(obj *ConfigMapVolumeSource) {
func SetDefaults_ConfigMapVolumeSource(obj *v1.ConfigMapVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(ConfigMapVolumeSourceDefaultMode)
perm := int32(v1.ConfigMapVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_DownwardAPIVolumeSource(obj *DownwardAPIVolumeSource) {
func SetDefaults_DownwardAPIVolumeSource(obj *v1.DownwardAPIVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(DownwardAPIVolumeSourceDefaultMode)
perm := int32(v1.DownwardAPIVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_Secret(obj *Secret) {
func SetDefaults_Secret(obj *v1.Secret) {
if obj.Type == "" {
obj.Type = SecretTypeOpaque
obj.Type = v1.SecretTypeOpaque
}
}
func SetDefaults_ProjectedVolumeSource(obj *ProjectedVolumeSource) {
func SetDefaults_ProjectedVolumeSource(obj *v1.ProjectedVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(ProjectedVolumeSourceDefaultMode)
perm := int32(v1.ProjectedVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_PersistentVolume(obj *PersistentVolume) {
func SetDefaults_PersistentVolume(obj *v1.PersistentVolume) {
if obj.Status.Phase == "" {
obj.Status.Phase = VolumePending
obj.Status.Phase = v1.VolumePending
}
if obj.Spec.PersistentVolumeReclaimPolicy == "" {
obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
obj.Spec.PersistentVolumeReclaimPolicy = v1.PersistentVolumeReclaimRetain
}
}
func SetDefaults_PersistentVolumeClaim(obj *PersistentVolumeClaim) {
func SetDefaults_PersistentVolumeClaim(obj *v1.PersistentVolumeClaim) {
if obj.Status.Phase == "" {
obj.Status.Phase = ClaimPending
obj.Status.Phase = v1.ClaimPending
}
}
func SetDefaults_ISCSIVolumeSource(obj *ISCSIVolumeSource) {
func SetDefaults_ISCSIVolumeSource(obj *v1.ISCSIVolumeSource) {
if obj.ISCSIInterface == "" {
obj.ISCSIInterface = "default"
}
}
func SetDefaults_AzureDiskVolumeSource(obj *AzureDiskVolumeSource) {
func SetDefaults_AzureDiskVolumeSource(obj *v1.AzureDiskVolumeSource) {
if obj.CachingMode == nil {
obj.CachingMode = new(AzureDataDiskCachingMode)
*obj.CachingMode = AzureDataDiskCachingReadWrite
obj.CachingMode = new(v1.AzureDataDiskCachingMode)
*obj.CachingMode = v1.AzureDataDiskCachingReadWrite
}
if obj.Kind == nil {
obj.Kind = new(AzureDataDiskKind)
*obj.Kind = AzureSharedBlobDisk
obj.Kind = new(v1.AzureDataDiskKind)
*obj.Kind = v1.AzureSharedBlobDisk
}
if obj.FSType == nil {
obj.FSType = new(string)
@ -254,58 +265,58 @@ func SetDefaults_AzureDiskVolumeSource(obj *AzureDiskVolumeSource) {
*obj.ReadOnly = false
}
}
func SetDefaults_Endpoints(obj *Endpoints) {
func SetDefaults_Endpoints(obj *v1.Endpoints) {
for i := range obj.Subsets {
ss := &obj.Subsets[i]
for i := range ss.Ports {
ep := &ss.Ports[i]
if ep.Protocol == "" {
ep.Protocol = ProtocolTCP
ep.Protocol = v1.ProtocolTCP
}
}
}
}
func SetDefaults_HTTPGetAction(obj *HTTPGetAction) {
func SetDefaults_HTTPGetAction(obj *v1.HTTPGetAction) {
if obj.Path == "" {
obj.Path = "/"
}
if obj.Scheme == "" {
obj.Scheme = URISchemeHTTP
obj.Scheme = v1.URISchemeHTTP
}
}
func SetDefaults_NamespaceStatus(obj *NamespaceStatus) {
func SetDefaults_NamespaceStatus(obj *v1.NamespaceStatus) {
if obj.Phase == "" {
obj.Phase = NamespaceActive
obj.Phase = v1.NamespaceActive
}
}
func SetDefaults_Node(obj *Node) {
func SetDefaults_Node(obj *v1.Node) {
if obj.Spec.ExternalID == "" {
obj.Spec.ExternalID = obj.Name
}
}
func SetDefaults_NodeStatus(obj *NodeStatus) {
func SetDefaults_NodeStatus(obj *v1.NodeStatus) {
if obj.Allocatable == nil && obj.Capacity != nil {
obj.Allocatable = make(ResourceList, len(obj.Capacity))
obj.Allocatable = make(v1.ResourceList, len(obj.Capacity))
for key, value := range obj.Capacity {
obj.Allocatable[key] = *(value.Copy())
}
obj.Allocatable = obj.Capacity
}
}
func SetDefaults_ObjectFieldSelector(obj *ObjectFieldSelector) {
func SetDefaults_ObjectFieldSelector(obj *v1.ObjectFieldSelector) {
if obj.APIVersion == "" {
obj.APIVersion = "v1"
}
}
func SetDefaults_LimitRangeItem(obj *LimitRangeItem) {
func SetDefaults_LimitRangeItem(obj *v1.LimitRangeItem) {
// for container limits, we apply default values
if obj.Type == LimitTypeContainer {
if obj.Type == v1.LimitTypeContainer {
if obj.Default == nil {
obj.Default = make(ResourceList)
obj.Default = make(v1.ResourceList)
}
if obj.DefaultRequest == nil {
obj.DefaultRequest = make(ResourceList)
obj.DefaultRequest = make(v1.ResourceList)
}
// If a default limit is unspecified, but the max is specified, default the limit to the max
@ -328,14 +339,14 @@ func SetDefaults_LimitRangeItem(obj *LimitRangeItem) {
}
}
}
func SetDefaults_ConfigMap(obj *ConfigMap) {
func SetDefaults_ConfigMap(obj *v1.ConfigMap) {
if obj.Data == nil {
obj.Data = make(map[string]string)
}
}
// With host networking default all container ports to host ports.
func defaultHostNetworkPorts(containers *[]Container) {
func defaultHostNetworkPorts(containers *[]v1.Container) {
for i := range *containers {
for j := range (*containers)[i].Ports {
if (*containers)[i].Ports[j].HostPort == 0 {
@ -345,7 +356,7 @@ func defaultHostNetworkPorts(containers *[]Container) {
}
}
func SetDefaults_RBDVolumeSource(obj *RBDVolumeSource) {
func SetDefaults_RBDVolumeSource(obj *v1.RBDVolumeSource) {
if obj.RBDPool == "" {
obj.RBDPool = "rbd"
}
@ -357,7 +368,7 @@ func SetDefaults_RBDVolumeSource(obj *RBDVolumeSource) {
}
}
func SetDefaults_ScaleIOVolumeSource(obj *ScaleIOVolumeSource) {
func SetDefaults_ScaleIOVolumeSource(obj *v1.ScaleIOVolumeSource) {
if obj.ProtectionDomain == "" {
obj.ProtectionDomain = "default"
}
@ -371,3 +382,10 @@ func SetDefaults_ScaleIOVolumeSource(obj *ScaleIOVolumeSource) {
obj.FSType = "xfs"
}
}
func SetDefaults_HostPathVolumeSource(obj *v1.HostPathVolumeSource) {
typeVol := v1.HostPathUnset
if obj.Type == nil {
obj.Type = &typeVol
}
}

View file

@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/api
// +k8s:openapi-gen=true
// +k8s:conversion-gen-external-types=../../../vendor/k8s.io/api/core/v1
// +k8s:defaulter-gen=TypeMeta
// +k8s:defaulter-gen-input=../../../vendor/k8s.io/api/core/v1
// Package v1 is the v1 version of the API.
package v1 // import "k8s.io/kubernetes/pkg/api/v1"

View file

@ -18,6 +18,7 @@ package v1
import (
"fmt"
"k8s.io/api/core/v1"
utilrand "k8s.io/apimachinery/pkg/util/rand"
)
@ -31,10 +32,10 @@ type NameGenerator interface {
GenerateName(base string) string
}
// GenerateName will resolve the object name of the provided ObjectMeta to a generated version if
// necessary. It expects that validation for ObjectMeta has already completed (that Base is a
// GenerateName will resolve the object name of the provided v1.ObjectMeta to a generated version if
// necessary. It expects that validation for v1.ObjectMeta has already completed (that Base is a
// valid name) and that the NameGenerator generates a name that is also valid.
func GenerateName(u NameGenerator, meta *ObjectMeta) {
func GenerateName(u NameGenerator, meta *v1.ObjectMeta) {
if len(meta.GenerateName) == 0 || len(meta.Name) != 0 {
return
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -21,14 +21,54 @@ import (
"fmt"
"strings"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/kubernetes/pkg/api"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/api/helper"
"k8s.io/kubernetes/pkg/api/v1"
)
// IsExtendedResourceName returns true if the resource name is not in the
// default namespace, or it has the opaque integer resource prefix.
func IsExtendedResourceName(name v1.ResourceName) bool {
// TODO: Remove OIR part following deprecation.
return !IsDefaultNamespaceResource(name) || IsOpaqueIntResourceName(name)
}
// IsDefaultNamespaceResource returns true if the resource name is in the
// *kubernetes.io/ namespace. Partially-qualified (unprefixed) names are
// implicitly in the kubernetes.io/ namespace.
func IsDefaultNamespaceResource(name v1.ResourceName) bool {
return !strings.Contains(string(name), "/") ||
strings.Contains(string(name), v1.ResourceDefaultNamespacePrefix)
}
// IsHugePageResourceName returns true if the resource name has the huge page
// resource prefix.
func IsHugePageResourceName(name v1.ResourceName) bool {
return strings.HasPrefix(string(name), v1.ResourceHugePagesPrefix)
}
// HugePageResourceName returns a ResourceName with the canonical hugepage
// prefix prepended for the specified page size. The page size is converted
// to its canonical representation.
func HugePageResourceName(pageSize resource.Quantity) v1.ResourceName {
return v1.ResourceName(fmt.Sprintf("%s%s", v1.ResourceHugePagesPrefix, pageSize.String()))
}
// HugePageSizeFromResourceName returns the page size for the specified huge page
// resource name. If the specified input is not a valid huge page resource name
// an error is returned.
func HugePageSizeFromResourceName(name v1.ResourceName) (resource.Quantity, error) {
if !IsHugePageResourceName(name) {
return resource.Quantity{}, fmt.Errorf("resource name: %s is not valid hugepage name", name)
}
pageSize := strings.TrimPrefix(string(name), v1.ResourceHugePagesPrefix)
return resource.ParseQuantity(pageSize)
}
// IsOpaqueIntResourceName returns true if the resource name has the opaque
// integer resource prefix.
func IsOpaqueIntResourceName(name v1.ResourceName) bool {
@ -45,6 +85,15 @@ func OpaqueIntResourceName(name string) v1.ResourceName {
return v1.ResourceName(fmt.Sprintf("%s%s", v1.ResourceOpaqueIntPrefix, name))
}
var overcommitBlacklist = sets.NewString(string(v1.ResourceNvidiaGPU))
// IsOvercommitAllowed returns true if the resource is in the default
// namespace and not blacklisted.
func IsOvercommitAllowed(name v1.ResourceName) bool {
return IsDefaultNamespaceResource(name) &&
!overcommitBlacklist.Has(string(name))
}
// this function aims to check if the service's ClusterIP is set or not
// the objective is not to perform validation here
func IsServiceIPSet(service *v1.Service) bool {
@ -269,34 +318,6 @@ func TolerationsTolerateTaintsWithFilter(tolerations []v1.Toleration, taints []v
return true
}
// DeleteTaintsByKey removes all the taints that have the same key to given taintKey
func DeleteTaintsByKey(taints []v1.Taint, taintKey string) ([]v1.Taint, bool) {
newTaints := []v1.Taint{}
deleted := false
for i := range taints {
if taintKey == taints[i].Key {
deleted = true
continue
}
newTaints = append(newTaints, taints[i])
}
return newTaints, deleted
}
// DeleteTaint removes all the the taints that have the same key and effect to given taintToDelete.
func DeleteTaint(taints []v1.Taint, taintToDelete *v1.Taint) ([]v1.Taint, bool) {
newTaints := []v1.Taint{}
deleted := false
for i := range taints {
if taintToDelete.MatchTaint(&taints[i]) {
deleted = true
continue
}
newTaints = append(newTaints, taints[i])
}
return newTaints, deleted
}
// Returns true and list of Tolerations matching all Taints if all are tolerated, or false otherwise.
func GetMatchingTolerations(taints []v1.Taint, tolerations []v1.Toleration) (bool, []v1.Toleration) {
if len(taints) == 0 {
@ -381,85 +402,6 @@ func PodAnnotationsFromSysctls(sysctls []v1.Sysctl) string {
return strings.Join(kvs, ",")
}
// Tries to add a taint to annotations list. Returns a new copy of updated Node and true if something was updated
// false otherwise.
func AddOrUpdateTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
objCopy, err := api.Scheme.DeepCopy(node)
if err != nil {
return nil, false, err
}
newNode := objCopy.(*v1.Node)
nodeTaints := newNode.Spec.Taints
var newTaints []v1.Taint
updated := false
for i := range nodeTaints {
if taint.MatchTaint(&nodeTaints[i]) {
if helper.Semantic.DeepEqual(taint, nodeTaints[i]) {
return newNode, false, nil
}
newTaints = append(newTaints, *taint)
updated = true
continue
}
newTaints = append(newTaints, nodeTaints[i])
}
if !updated {
newTaints = append(newTaints, *taint)
}
newNode.Spec.Taints = newTaints
return newNode, true, nil
}
func TaintExists(taints []v1.Taint, taintToFind *v1.Taint) bool {
for _, taint := range taints {
if taint.MatchTaint(taintToFind) {
return true
}
}
return false
}
// Tries to remove a taint from annotations list. Returns a new copy of updated Node and true if something was updated
// false otherwise.
func RemoveTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
objCopy, err := api.Scheme.DeepCopy(node)
if err != nil {
return nil, false, err
}
newNode := objCopy.(*v1.Node)
nodeTaints := newNode.Spec.Taints
if len(nodeTaints) == 0 {
return newNode, false, nil
}
if !TaintExists(nodeTaints, taint) {
return newNode, false, nil
}
newTaints, _ := DeleteTaint(nodeTaints, taint)
newNode.Spec.Taints = newTaints
return newNode, true, nil
}
// GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations
// and converts it to the Affinity type in api.
// TODO: remove when alpha support for affinity is removed
func GetAffinityFromPodAnnotations(annotations map[string]string) (*v1.Affinity, error) {
if len(annotations) > 0 && annotations[v1.AffinityAnnotationKey] != "" {
var affinity v1.Affinity
err := json.Unmarshal([]byte(annotations[v1.AffinityAnnotationKey]), &affinity)
if err != nil {
return nil, err
}
return &affinity, nil
}
return nil, nil
}
// GetPersistentVolumeClass returns StorageClassName.
func GetPersistentVolumeClass(volume *v1.PersistentVolume) string {
// Use beta annotation first

View file

@ -1,108 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
func (obj *ObjectMeta) GetObjectMeta() metav1.Object { return obj }
// Namespace implements metav1.Object for any object with an ObjectMeta typed field. Allows
// fast, direct access to metadata fields for API objects.
func (meta *ObjectMeta) GetNamespace() string { return meta.Namespace }
func (meta *ObjectMeta) SetNamespace(namespace string) { meta.Namespace = namespace }
func (meta *ObjectMeta) GetName() string { return meta.Name }
func (meta *ObjectMeta) SetName(name string) { meta.Name = name }
func (meta *ObjectMeta) GetGenerateName() string { return meta.GenerateName }
func (meta *ObjectMeta) SetGenerateName(generateName string) { meta.GenerateName = generateName }
func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
func (meta *ObjectMeta) GetGeneration() int64 { return meta.Generation }
func (meta *ObjectMeta) SetGeneration(generation int64) { meta.Generation = generation }
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
func (meta *ObjectMeta) GetCreationTimestamp() metav1.Time { return meta.CreationTimestamp }
func (meta *ObjectMeta) SetCreationTimestamp(creationTimestamp metav1.Time) {
meta.CreationTimestamp = creationTimestamp
}
func (meta *ObjectMeta) GetDeletionTimestamp() *metav1.Time { return meta.DeletionTimestamp }
func (meta *ObjectMeta) SetDeletionTimestamp(deletionTimestamp *metav1.Time) {
meta.DeletionTimestamp = deletionTimestamp
}
func (meta *ObjectMeta) GetDeletionGracePeriodSeconds() *int64 { return meta.DeletionGracePeriodSeconds }
func (meta *ObjectMeta) SetDeletionGracePeriodSeconds(deletionGracePeriodSeconds *int64) {
meta.DeletionGracePeriodSeconds = deletionGracePeriodSeconds
}
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations }
func (meta *ObjectMeta) GetInitializers() *metav1.Initializers { return meta.Initializers }
func (meta *ObjectMeta) SetInitializers(initializers *metav1.Initializers) {
meta.Initializers = initializers
}
func (meta *ObjectMeta) GetFinalizers() []string { return meta.Finalizers }
func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers }
func (meta *ObjectMeta) GetOwnerReferences() []metav1.OwnerReference {
ret := make([]metav1.OwnerReference, len(meta.OwnerReferences))
for i := 0; i < len(meta.OwnerReferences); i++ {
ret[i].Kind = meta.OwnerReferences[i].Kind
ret[i].Name = meta.OwnerReferences[i].Name
ret[i].UID = meta.OwnerReferences[i].UID
ret[i].APIVersion = meta.OwnerReferences[i].APIVersion
if meta.OwnerReferences[i].Controller != nil {
value := *meta.OwnerReferences[i].Controller
ret[i].Controller = &value
}
if meta.OwnerReferences[i].BlockOwnerDeletion != nil {
value := *meta.OwnerReferences[i].BlockOwnerDeletion
ret[i].BlockOwnerDeletion = &value
}
}
return ret
}
func (meta *ObjectMeta) SetOwnerReferences(references []metav1.OwnerReference) {
newReferences := make([]metav1.OwnerReference, len(references))
for i := 0; i < len(references); i++ {
newReferences[i].Kind = references[i].Kind
newReferences[i].Name = references[i].Name
newReferences[i].UID = references[i].UID
newReferences[i].APIVersion = references[i].APIVersion
if references[i].Controller != nil {
value := *references[i].Controller
newReferences[i].Controller = &value
}
if references[i].BlockOwnerDeletion != nil {
value := *references[i].BlockOwnerDeletion
newReferences[i].BlockOwnerDeletion = &value
}
}
meta.OwnerReferences = newReferences
}
func (meta *ObjectMeta) GetClusterName() string {
return meta.ClusterName
}
func (meta *ObjectMeta) SetClusterName(clusterName string) {
meta.ClusterName = clusterName
}

View file

@ -1,33 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
)
// IsAnAPIObject allows clients to preemptively get a reference to an API object and pass it to places that
// intend only to get a reference to that object. This simplifies the event recording interface.
func (obj *ObjectReference) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ObjectReference) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *ObjectReference) GetObjectKind() schema.ObjectKind { return obj }

View file

@ -17,13 +17,12 @@ limitations under the License.
package pod
import (
"encoding/json"
"fmt"
"time"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/api/v1"
)
// FindPort locates the container port for the given pod and portName. If the
@ -49,67 +48,6 @@ func FindPort(pod *v1.Pod, svcPort *v1.ServicePort) (int, error) {
return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
}
// TODO: remove this function when init containers becomes a stable feature
func SetInitContainersAndStatuses(pod *v1.Pod) error {
var initContainersAnnotation string
initContainersAnnotation = pod.Annotations[v1.PodInitContainersAnnotationKey]
initContainersAnnotation = pod.Annotations[v1.PodInitContainersBetaAnnotationKey]
if len(initContainersAnnotation) > 0 {
var values []v1.Container
if err := json.Unmarshal([]byte(initContainersAnnotation), &values); err != nil {
return err
}
pod.Spec.InitContainers = values
}
var initContainerStatusesAnnotation string
initContainerStatusesAnnotation = pod.Annotations[v1.PodInitContainerStatusesAnnotationKey]
initContainerStatusesAnnotation = pod.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey]
if len(initContainerStatusesAnnotation) > 0 {
var values []v1.ContainerStatus
if err := json.Unmarshal([]byte(initContainerStatusesAnnotation), &values); err != nil {
return err
}
pod.Status.InitContainerStatuses = values
}
return nil
}
// TODO: remove this function when init containers becomes a stable feature
func SetInitContainersAnnotations(pod *v1.Pod) error {
if len(pod.Spec.InitContainers) > 0 {
value, err := json.Marshal(pod.Spec.InitContainers)
if err != nil {
return err
}
if pod.Annotations == nil {
pod.Annotations = make(map[string]string)
}
pod.Annotations[v1.PodInitContainersAnnotationKey] = string(value)
pod.Annotations[v1.PodInitContainersBetaAnnotationKey] = string(value)
}
return nil
}
// TODO: remove this function when init containers becomes a stable feature
func SetInitContainersStatusesAnnotations(pod *v1.Pod) error {
if len(pod.Status.InitContainerStatuses) > 0 {
value, err := json.Marshal(pod.Status.InitContainerStatuses)
if err != nil {
return err
}
if pod.Annotations == nil {
pod.Annotations = make(map[string]string)
}
pod.Annotations[v1.PodInitContainerStatusesAnnotationKey] = string(value)
pod.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey] = string(value)
} else {
delete(pod.Annotations, v1.PodInitContainerStatusesAnnotationKey)
delete(pod.Annotations, v1.PodInitContainerStatusesBetaAnnotationKey)
}
return nil
}
// Visitor is called with each object name, and returns true if visiting should continue
type Visitor func(name string) (shouldContinue bool)
@ -348,8 +286,8 @@ func UpdatePodCondition(status *v1.PodStatus, condition *v1.PodCondition) bool {
isEqual := condition.Status == oldCondition.Status &&
condition.Reason == oldCondition.Reason &&
condition.Message == oldCondition.Message &&
condition.LastProbeTime.Equal(oldCondition.LastProbeTime) &&
condition.LastTransitionTime.Equal(oldCondition.LastTransitionTime)
condition.LastProbeTime.Equal(&oldCondition.LastProbeTime) &&
condition.LastTransitionTime.Equal(&oldCondition.LastTransitionTime)
status.Conditions[conditionIndex] = *condition
// Return true if one of the fields have changed.

View file

@ -1,121 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ref
import (
"errors"
"fmt"
"net/url"
"strings"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api/v1"
)
var (
// Errors that could be returned by GetReference.
ErrNilObject = errors.New("can't reference a nil object")
ErrNoSelfLink = errors.New("selfLink was empty, can't make reference")
)
// GetReference returns an ObjectReference which refers to the given
// object, or an error if the object doesn't follow the conventions
// that would allow this.
// TODO: should take a meta.Interface see http://issue.k8s.io/7127
func GetReference(scheme *runtime.Scheme, obj runtime.Object) (*v1.ObjectReference, error) {
if obj == nil {
return nil, ErrNilObject
}
if ref, ok := obj.(*v1.ObjectReference); ok {
// Don't make a reference to a reference.
return ref, nil
}
gvk := obj.GetObjectKind().GroupVersionKind()
// if the object referenced is actually persisted, we can just get kind from meta
// if we are building an object reference to something not yet persisted, we should fallback to scheme
kind := gvk.Kind
if len(kind) == 0 {
// TODO: this is wrong
gvks, _, err := scheme.ObjectKinds(obj)
if err != nil {
return nil, err
}
kind = gvks[0].Kind
}
// An object that implements only List has enough metadata to build a reference
var listMeta meta.List
objectMeta, err := meta.Accessor(obj)
if err != nil {
listMeta, err = meta.ListAccessor(obj)
if err != nil {
return nil, err
}
} else {
listMeta = objectMeta
}
// if the object referenced is actually persisted, we can also get version from meta
version := gvk.GroupVersion().String()
if len(version) == 0 {
selfLink := listMeta.GetSelfLink()
if len(selfLink) == 0 {
return nil, ErrNoSelfLink
}
selfLinkUrl, err := url.Parse(selfLink)
if err != nil {
return nil, err
}
// example paths: /<prefix>/<version>/*
parts := strings.Split(selfLinkUrl.Path, "/")
if len(parts) < 3 {
return nil, fmt.Errorf("unexpected self link format: '%v'; got version '%v'", selfLink, version)
}
version = parts[2]
}
// only has list metadata
if objectMeta == nil {
return &v1.ObjectReference{
Kind: kind,
APIVersion: version,
ResourceVersion: listMeta.GetResourceVersion(),
}, nil
}
return &v1.ObjectReference{
Kind: kind,
APIVersion: version,
Name: objectMeta.GetName(),
Namespace: objectMeta.GetNamespace(),
UID: objectMeta.GetUID(),
ResourceVersion: objectMeta.GetResourceVersion(),
}, nil
}
// GetPartialReference is exactly like GetReference, but allows you to set the FieldPath.
func GetPartialReference(scheme *runtime.Scheme, obj runtime.Object, fieldPath string) (*v1.ObjectReference, error) {
ref, err := GetReference(scheme, obj)
if err != nil {
return nil, err
}
ref.FieldPath = fieldPath
return ref, nil
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors.
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -17,11 +17,23 @@ limitations under the License.
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var (
localSchemeBuilder = &v1.SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addDefaultingFuncs, addConversionFuncs, addFastPathConversionFuncs)
}
// TODO: remove these global varialbes
// GroupName is the group name use in this package
const GroupName = ""
@ -32,75 +44,3 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs, addConversionFuncs, addFastPathConversionFuncs)
}
// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Pod{},
&PodList{},
&PodStatusResult{},
&PodTemplate{},
&PodTemplateList{},
&ReplicationController{},
&ReplicationControllerList{},
&Service{},
&ServiceProxyOptions{},
&ServiceList{},
&Endpoints{},
&EndpointsList{},
&Node{},
&NodeList{},
&NodeProxyOptions{},
&Binding{},
&Event{},
&EventList{},
&List{},
&LimitRange{},
&LimitRangeList{},
&ResourceQuota{},
&ResourceQuotaList{},
&Namespace{},
&NamespaceList{},
&Secret{},
&SecretList{},
&ServiceAccount{},
&ServiceAccountList{},
&PersistentVolume{},
&PersistentVolumeList{},
&PersistentVolumeClaim{},
&PersistentVolumeClaimList{},
&PodAttachOptions{},
&PodLogOptions{},
&PodExecOptions{},
&PodPortForwardOptions{},
&PodProxyOptions{},
&ComponentStatus{},
&ComponentStatusList{},
&SerializedReference{},
&RangeAllocation{},
&ConfigMap{},
&ConfigMapList{},
)
// Add common types
scheme.AddKnownTypes(SchemeGroupVersion, &metav1.Status{})
// Add the watch version that applies
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View file

@ -1,63 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"k8s.io/apimachinery/pkg/api/resource"
)
// Returns string version of ResourceName.
func (self ResourceName) String() string {
return string(self)
}
// Returns the CPU limit if specified.
func (self *ResourceList) Cpu() *resource.Quantity {
if val, ok := (*self)[ResourceCPU]; ok {
return &val
}
return &resource.Quantity{Format: resource.DecimalSI}
}
// Returns the Memory limit if specified.
func (self *ResourceList) Memory() *resource.Quantity {
if val, ok := (*self)[ResourceMemory]; ok {
return &val
}
return &resource.Quantity{Format: resource.BinarySI}
}
func (self *ResourceList) Pods() *resource.Quantity {
if val, ok := (*self)[ResourcePods]; ok {
return &val
}
return &resource.Quantity{}
}
func (self *ResourceList) NvidiaGPU() *resource.Quantity {
if val, ok := (*self)[ResourceNvidiaGPU]; ok {
return &val
}
return &resource.Quantity{}
}
func (self *ResourceList) StorageOverlay() *resource.Quantity {
if val, ok := (*self)[ResourceStorageOverlay]; ok {
return &val
}
return &resource.Quantity{}
}

View file

@ -1,33 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import "fmt"
// MatchTaint checks if the taint matches taintToMatch. Taints are unique by key:effect,
// if the two taints have same key:effect, regard as they match.
func (t *Taint) MatchTaint(taintToMatch *Taint) bool {
return t.Key == taintToMatch.Key && t.Effect == taintToMatch.Effect
}
// taint.ToString() converts taint struct to string in format key=value:effect or key:effect.
func (t *Taint) ToString() string {
if len(t.Value) == 0 {
return fmt.Sprintf("%v:%v", t.Key, t.Effect)
}
return fmt.Sprintf("%v=%v:%v", t.Key, t.Value, t.Effect)
}

View file

@ -1,56 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
// MatchToleration checks if the toleration matches tolerationToMatch. Tolerations are unique by <key,effect,operator,value>,
// if the two tolerations have same <key,effect,operator,value> combination, regard as they match.
// TODO: uniqueness check for tolerations in api validations.
func (t *Toleration) MatchToleration(tolerationToMatch *Toleration) bool {
return t.Key == tolerationToMatch.Key &&
t.Effect == tolerationToMatch.Effect &&
t.Operator == tolerationToMatch.Operator &&
t.Value == tolerationToMatch.Value
}
// ToleratesTaint checks if the toleration tolerates the taint.
// The matching follows the rules below:
// (1) Empty toleration.effect means to match all taint effects,
// otherwise taint effect must equal to toleration.effect.
// (2) If toleration.operator is 'Exists', it means to match all taint values.
// (3) Empty toleration.key means to match all taint keys.
// If toleration.key is empty, toleration.operator must be 'Exists';
// this combination means to match all taint values and all taint keys.
func (t *Toleration) ToleratesTaint(taint *Taint) bool {
if len(t.Effect) > 0 && t.Effect != taint.Effect {
return false
}
if len(t.Key) > 0 && t.Key != taint.Key {
return false
}
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
switch t.Operator {
// empty operator means Equal
case "", TolerationOpEqual:
return t.Value == taint.Value
case TolerationOpExists:
return true
default:
return false
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,7 @@ limitations under the License.
package v1
import (
v1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@ -28,60 +29,64 @@ import (
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&ConfigMap{}, func(obj interface{}) { SetObjectDefaults_ConfigMap(obj.(*ConfigMap)) })
scheme.AddTypeDefaultingFunc(&ConfigMapList{}, func(obj interface{}) { SetObjectDefaults_ConfigMapList(obj.(*ConfigMapList)) })
scheme.AddTypeDefaultingFunc(&Endpoints{}, func(obj interface{}) { SetObjectDefaults_Endpoints(obj.(*Endpoints)) })
scheme.AddTypeDefaultingFunc(&EndpointsList{}, func(obj interface{}) { SetObjectDefaults_EndpointsList(obj.(*EndpointsList)) })
scheme.AddTypeDefaultingFunc(&LimitRange{}, func(obj interface{}) { SetObjectDefaults_LimitRange(obj.(*LimitRange)) })
scheme.AddTypeDefaultingFunc(&LimitRangeList{}, func(obj interface{}) { SetObjectDefaults_LimitRangeList(obj.(*LimitRangeList)) })
scheme.AddTypeDefaultingFunc(&Namespace{}, func(obj interface{}) { SetObjectDefaults_Namespace(obj.(*Namespace)) })
scheme.AddTypeDefaultingFunc(&NamespaceList{}, func(obj interface{}) { SetObjectDefaults_NamespaceList(obj.(*NamespaceList)) })
scheme.AddTypeDefaultingFunc(&Node{}, func(obj interface{}) { SetObjectDefaults_Node(obj.(*Node)) })
scheme.AddTypeDefaultingFunc(&NodeList{}, func(obj interface{}) { SetObjectDefaults_NodeList(obj.(*NodeList)) })
scheme.AddTypeDefaultingFunc(&PersistentVolume{}, func(obj interface{}) { SetObjectDefaults_PersistentVolume(obj.(*PersistentVolume)) })
scheme.AddTypeDefaultingFunc(&PersistentVolumeClaim{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeClaim(obj.(*PersistentVolumeClaim)) })
scheme.AddTypeDefaultingFunc(&PersistentVolumeClaimList{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeClaimList(obj.(*PersistentVolumeClaimList)) })
scheme.AddTypeDefaultingFunc(&PersistentVolumeList{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeList(obj.(*PersistentVolumeList)) })
scheme.AddTypeDefaultingFunc(&Pod{}, func(obj interface{}) { SetObjectDefaults_Pod(obj.(*Pod)) })
scheme.AddTypeDefaultingFunc(&PodAttachOptions{}, func(obj interface{}) { SetObjectDefaults_PodAttachOptions(obj.(*PodAttachOptions)) })
scheme.AddTypeDefaultingFunc(&PodExecOptions{}, func(obj interface{}) { SetObjectDefaults_PodExecOptions(obj.(*PodExecOptions)) })
scheme.AddTypeDefaultingFunc(&PodList{}, func(obj interface{}) { SetObjectDefaults_PodList(obj.(*PodList)) })
scheme.AddTypeDefaultingFunc(&PodTemplate{}, func(obj interface{}) { SetObjectDefaults_PodTemplate(obj.(*PodTemplate)) })
scheme.AddTypeDefaultingFunc(&PodTemplateList{}, func(obj interface{}) { SetObjectDefaults_PodTemplateList(obj.(*PodTemplateList)) })
scheme.AddTypeDefaultingFunc(&ReplicationController{}, func(obj interface{}) { SetObjectDefaults_ReplicationController(obj.(*ReplicationController)) })
scheme.AddTypeDefaultingFunc(&ReplicationControllerList{}, func(obj interface{}) { SetObjectDefaults_ReplicationControllerList(obj.(*ReplicationControllerList)) })
scheme.AddTypeDefaultingFunc(&ResourceQuota{}, func(obj interface{}) { SetObjectDefaults_ResourceQuota(obj.(*ResourceQuota)) })
scheme.AddTypeDefaultingFunc(&ResourceQuotaList{}, func(obj interface{}) { SetObjectDefaults_ResourceQuotaList(obj.(*ResourceQuotaList)) })
scheme.AddTypeDefaultingFunc(&Secret{}, func(obj interface{}) { SetObjectDefaults_Secret(obj.(*Secret)) })
scheme.AddTypeDefaultingFunc(&SecretList{}, func(obj interface{}) { SetObjectDefaults_SecretList(obj.(*SecretList)) })
scheme.AddTypeDefaultingFunc(&Service{}, func(obj interface{}) { SetObjectDefaults_Service(obj.(*Service)) })
scheme.AddTypeDefaultingFunc(&ServiceList{}, func(obj interface{}) { SetObjectDefaults_ServiceList(obj.(*ServiceList)) })
scheme.AddTypeDefaultingFunc(&v1.ConfigMap{}, func(obj interface{}) { SetObjectDefaults_ConfigMap(obj.(*v1.ConfigMap)) })
scheme.AddTypeDefaultingFunc(&v1.ConfigMapList{}, func(obj interface{}) { SetObjectDefaults_ConfigMapList(obj.(*v1.ConfigMapList)) })
scheme.AddTypeDefaultingFunc(&v1.Endpoints{}, func(obj interface{}) { SetObjectDefaults_Endpoints(obj.(*v1.Endpoints)) })
scheme.AddTypeDefaultingFunc(&v1.EndpointsList{}, func(obj interface{}) { SetObjectDefaults_EndpointsList(obj.(*v1.EndpointsList)) })
scheme.AddTypeDefaultingFunc(&v1.LimitRange{}, func(obj interface{}) { SetObjectDefaults_LimitRange(obj.(*v1.LimitRange)) })
scheme.AddTypeDefaultingFunc(&v1.LimitRangeList{}, func(obj interface{}) { SetObjectDefaults_LimitRangeList(obj.(*v1.LimitRangeList)) })
scheme.AddTypeDefaultingFunc(&v1.Namespace{}, func(obj interface{}) { SetObjectDefaults_Namespace(obj.(*v1.Namespace)) })
scheme.AddTypeDefaultingFunc(&v1.NamespaceList{}, func(obj interface{}) { SetObjectDefaults_NamespaceList(obj.(*v1.NamespaceList)) })
scheme.AddTypeDefaultingFunc(&v1.Node{}, func(obj interface{}) { SetObjectDefaults_Node(obj.(*v1.Node)) })
scheme.AddTypeDefaultingFunc(&v1.NodeList{}, func(obj interface{}) { SetObjectDefaults_NodeList(obj.(*v1.NodeList)) })
scheme.AddTypeDefaultingFunc(&v1.PersistentVolume{}, func(obj interface{}) { SetObjectDefaults_PersistentVolume(obj.(*v1.PersistentVolume)) })
scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeClaim{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeClaim(obj.(*v1.PersistentVolumeClaim)) })
scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeClaimList{}, func(obj interface{}) {
SetObjectDefaults_PersistentVolumeClaimList(obj.(*v1.PersistentVolumeClaimList))
})
scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeList{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeList(obj.(*v1.PersistentVolumeList)) })
scheme.AddTypeDefaultingFunc(&v1.Pod{}, func(obj interface{}) { SetObjectDefaults_Pod(obj.(*v1.Pod)) })
scheme.AddTypeDefaultingFunc(&v1.PodAttachOptions{}, func(obj interface{}) { SetObjectDefaults_PodAttachOptions(obj.(*v1.PodAttachOptions)) })
scheme.AddTypeDefaultingFunc(&v1.PodExecOptions{}, func(obj interface{}) { SetObjectDefaults_PodExecOptions(obj.(*v1.PodExecOptions)) })
scheme.AddTypeDefaultingFunc(&v1.PodList{}, func(obj interface{}) { SetObjectDefaults_PodList(obj.(*v1.PodList)) })
scheme.AddTypeDefaultingFunc(&v1.PodTemplate{}, func(obj interface{}) { SetObjectDefaults_PodTemplate(obj.(*v1.PodTemplate)) })
scheme.AddTypeDefaultingFunc(&v1.PodTemplateList{}, func(obj interface{}) { SetObjectDefaults_PodTemplateList(obj.(*v1.PodTemplateList)) })
scheme.AddTypeDefaultingFunc(&v1.ReplicationController{}, func(obj interface{}) { SetObjectDefaults_ReplicationController(obj.(*v1.ReplicationController)) })
scheme.AddTypeDefaultingFunc(&v1.ReplicationControllerList{}, func(obj interface{}) {
SetObjectDefaults_ReplicationControllerList(obj.(*v1.ReplicationControllerList))
})
scheme.AddTypeDefaultingFunc(&v1.ResourceQuota{}, func(obj interface{}) { SetObjectDefaults_ResourceQuota(obj.(*v1.ResourceQuota)) })
scheme.AddTypeDefaultingFunc(&v1.ResourceQuotaList{}, func(obj interface{}) { SetObjectDefaults_ResourceQuotaList(obj.(*v1.ResourceQuotaList)) })
scheme.AddTypeDefaultingFunc(&v1.Secret{}, func(obj interface{}) { SetObjectDefaults_Secret(obj.(*v1.Secret)) })
scheme.AddTypeDefaultingFunc(&v1.SecretList{}, func(obj interface{}) { SetObjectDefaults_SecretList(obj.(*v1.SecretList)) })
scheme.AddTypeDefaultingFunc(&v1.Service{}, func(obj interface{}) { SetObjectDefaults_Service(obj.(*v1.Service)) })
scheme.AddTypeDefaultingFunc(&v1.ServiceList{}, func(obj interface{}) { SetObjectDefaults_ServiceList(obj.(*v1.ServiceList)) })
return nil
}
func SetObjectDefaults_ConfigMap(in *ConfigMap) {
func SetObjectDefaults_ConfigMap(in *v1.ConfigMap) {
SetDefaults_ConfigMap(in)
}
func SetObjectDefaults_ConfigMapList(in *ConfigMapList) {
func SetObjectDefaults_ConfigMapList(in *v1.ConfigMapList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_ConfigMap(a)
}
}
func SetObjectDefaults_Endpoints(in *Endpoints) {
func SetObjectDefaults_Endpoints(in *v1.Endpoints) {
SetDefaults_Endpoints(in)
}
func SetObjectDefaults_EndpointsList(in *EndpointsList) {
func SetObjectDefaults_EndpointsList(in *v1.EndpointsList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_Endpoints(a)
}
}
func SetObjectDefaults_LimitRange(in *LimitRange) {
func SetObjectDefaults_LimitRange(in *v1.LimitRange) {
for i := range in.Spec.Limits {
a := &in.Spec.Limits[i]
SetDefaults_LimitRangeItem(a)
@ -93,41 +98,44 @@ func SetObjectDefaults_LimitRange(in *LimitRange) {
}
}
func SetObjectDefaults_LimitRangeList(in *LimitRangeList) {
func SetObjectDefaults_LimitRangeList(in *v1.LimitRangeList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_LimitRange(a)
}
}
func SetObjectDefaults_Namespace(in *Namespace) {
func SetObjectDefaults_Namespace(in *v1.Namespace) {
SetDefaults_NamespaceStatus(&in.Status)
}
func SetObjectDefaults_NamespaceList(in *NamespaceList) {
func SetObjectDefaults_NamespaceList(in *v1.NamespaceList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_Namespace(a)
}
}
func SetObjectDefaults_Node(in *Node) {
func SetObjectDefaults_Node(in *v1.Node) {
SetDefaults_Node(in)
SetDefaults_NodeStatus(&in.Status)
SetDefaults_ResourceList(&in.Status.Capacity)
SetDefaults_ResourceList(&in.Status.Allocatable)
}
func SetObjectDefaults_NodeList(in *NodeList) {
func SetObjectDefaults_NodeList(in *v1.NodeList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_Node(a)
}
}
func SetObjectDefaults_PersistentVolume(in *PersistentVolume) {
func SetObjectDefaults_PersistentVolume(in *v1.PersistentVolume) {
SetDefaults_PersistentVolume(in)
SetDefaults_ResourceList(&in.Spec.Capacity)
if in.Spec.PersistentVolumeSource.HostPath != nil {
SetDefaults_HostPathVolumeSource(in.Spec.PersistentVolumeSource.HostPath)
}
if in.Spec.PersistentVolumeSource.RBD != nil {
SetDefaults_RBDVolumeSource(in.Spec.PersistentVolumeSource.RBD)
}
@ -142,33 +150,36 @@ func SetObjectDefaults_PersistentVolume(in *PersistentVolume) {
}
}
func SetObjectDefaults_PersistentVolumeClaim(in *PersistentVolumeClaim) {
func SetObjectDefaults_PersistentVolumeClaim(in *v1.PersistentVolumeClaim) {
SetDefaults_PersistentVolumeClaim(in)
SetDefaults_ResourceList(&in.Spec.Resources.Limits)
SetDefaults_ResourceList(&in.Spec.Resources.Requests)
SetDefaults_ResourceList(&in.Status.Capacity)
}
func SetObjectDefaults_PersistentVolumeClaimList(in *PersistentVolumeClaimList) {
func SetObjectDefaults_PersistentVolumeClaimList(in *v1.PersistentVolumeClaimList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_PersistentVolumeClaim(a)
}
}
func SetObjectDefaults_PersistentVolumeList(in *PersistentVolumeList) {
func SetObjectDefaults_PersistentVolumeList(in *v1.PersistentVolumeList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_PersistentVolume(a)
}
}
func SetObjectDefaults_Pod(in *Pod) {
func SetObjectDefaults_Pod(in *v1.Pod) {
SetDefaults_Pod(in)
SetDefaults_PodSpec(&in.Spec)
for i := range in.Spec.Volumes {
a := &in.Spec.Volumes[i]
SetDefaults_Volume(a)
if a.VolumeSource.HostPath != nil {
SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
}
if a.VolumeSource.Secret != nil {
SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
}
@ -297,26 +308,29 @@ func SetObjectDefaults_Pod(in *Pod) {
}
}
func SetObjectDefaults_PodAttachOptions(in *PodAttachOptions) {
func SetObjectDefaults_PodAttachOptions(in *v1.PodAttachOptions) {
SetDefaults_PodAttachOptions(in)
}
func SetObjectDefaults_PodExecOptions(in *PodExecOptions) {
func SetObjectDefaults_PodExecOptions(in *v1.PodExecOptions) {
SetDefaults_PodExecOptions(in)
}
func SetObjectDefaults_PodList(in *PodList) {
func SetObjectDefaults_PodList(in *v1.PodList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_Pod(a)
}
}
func SetObjectDefaults_PodTemplate(in *PodTemplate) {
func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) {
SetDefaults_PodSpec(&in.Template.Spec)
for i := range in.Template.Spec.Volumes {
a := &in.Template.Spec.Volumes[i]
SetDefaults_Volume(a)
if a.VolumeSource.HostPath != nil {
SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
}
if a.VolumeSource.Secret != nil {
SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
}
@ -445,20 +459,23 @@ func SetObjectDefaults_PodTemplate(in *PodTemplate) {
}
}
func SetObjectDefaults_PodTemplateList(in *PodTemplateList) {
func SetObjectDefaults_PodTemplateList(in *v1.PodTemplateList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_PodTemplate(a)
}
}
func SetObjectDefaults_ReplicationController(in *ReplicationController) {
func SetObjectDefaults_ReplicationController(in *v1.ReplicationController) {
SetDefaults_ReplicationController(in)
if in.Spec.Template != nil {
SetDefaults_PodSpec(&in.Spec.Template.Spec)
for i := range in.Spec.Template.Spec.Volumes {
a := &in.Spec.Template.Spec.Volumes[i]
SetDefaults_Volume(a)
if a.VolumeSource.HostPath != nil {
SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
}
if a.VolumeSource.Secret != nil {
SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
}
@ -588,42 +605,42 @@ func SetObjectDefaults_ReplicationController(in *ReplicationController) {
}
}
func SetObjectDefaults_ReplicationControllerList(in *ReplicationControllerList) {
func SetObjectDefaults_ReplicationControllerList(in *v1.ReplicationControllerList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_ReplicationController(a)
}
}
func SetObjectDefaults_ResourceQuota(in *ResourceQuota) {
func SetObjectDefaults_ResourceQuota(in *v1.ResourceQuota) {
SetDefaults_ResourceList(&in.Spec.Hard)
SetDefaults_ResourceList(&in.Status.Hard)
SetDefaults_ResourceList(&in.Status.Used)
}
func SetObjectDefaults_ResourceQuotaList(in *ResourceQuotaList) {
func SetObjectDefaults_ResourceQuotaList(in *v1.ResourceQuotaList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_ResourceQuota(a)
}
}
func SetObjectDefaults_Secret(in *Secret) {
func SetObjectDefaults_Secret(in *v1.Secret) {
SetDefaults_Secret(in)
}
func SetObjectDefaults_SecretList(in *SecretList) {
func SetObjectDefaults_SecretList(in *v1.SecretList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_Secret(a)
}
}
func SetObjectDefaults_Service(in *Service) {
func SetObjectDefaults_Service(in *v1.Service) {
SetDefaults_Service(in)
}
func SetObjectDefaults_ServiceList(in *ServiceList) {
func SetObjectDefaults_ServiceList(in *v1.ServiceList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_Service(a)

View file

@ -1,435 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"regexp"
"strings"
"github.com/emicklei/go-restful-swagger12"
ejson "github.com/exponent-io/jsonpath"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/yaml"
apiutil "k8s.io/kubernetes/pkg/api/util"
)
type InvalidTypeError struct {
ExpectedKind reflect.Kind
ObservedKind reflect.Kind
FieldName string
}
func (i *InvalidTypeError) Error() string {
return fmt.Sprintf("expected type %s, for field %s, got %s", i.ExpectedKind.String(), i.FieldName, i.ObservedKind.String())
}
func NewInvalidTypeError(expected reflect.Kind, observed reflect.Kind, fieldName string) error {
return &InvalidTypeError{expected, observed, fieldName}
}
// TypeNotFoundError is returned when specified type
// can not found in schema
type TypeNotFoundError string
func (tnfe TypeNotFoundError) Error() string {
return fmt.Sprintf("couldn't find type: %s", string(tnfe))
}
// Schema is an interface that knows how to validate an API object serialized to a byte array.
type Schema interface {
ValidateBytes(data []byte) error
}
type NullSchema struct{}
func (NullSchema) ValidateBytes(data []byte) error { return nil }
type NoDoubleKeySchema struct{}
func (NoDoubleKeySchema) ValidateBytes(data []byte) error {
var list []error = nil
if err := validateNoDuplicateKeys(data, "metadata", "labels"); err != nil {
list = append(list, err)
}
if err := validateNoDuplicateKeys(data, "metadata", "annotations"); err != nil {
list = append(list, err)
}
return utilerrors.NewAggregate(list)
}
func validateNoDuplicateKeys(data []byte, path ...string) error {
r := ejson.NewDecoder(bytes.NewReader(data))
// This is Go being unfriendly. The 'path ...string' comes in as a
// []string, and SeekTo takes ...interface{}, so we can't just pass
// the path straight in, we have to copy it. *sigh*
ifacePath := []interface{}{}
for ix := range path {
ifacePath = append(ifacePath, path[ix])
}
found, err := r.SeekTo(ifacePath...)
if err != nil {
return err
}
if !found {
return nil
}
seen := map[string]bool{}
for {
tok, err := r.Token()
if err != nil {
return err
}
switch t := tok.(type) {
case json.Delim:
if t.String() == "}" {
return nil
}
case ejson.KeyString:
if seen[string(t)] {
return fmt.Errorf("duplicate key: %s", string(t))
} else {
seen[string(t)] = true
}
}
}
}
type ConjunctiveSchema []Schema
func (c ConjunctiveSchema) ValidateBytes(data []byte) error {
var list []error = nil
schemas := []Schema(c)
for ix := range schemas {
if err := schemas[ix].ValidateBytes(data); err != nil {
list = append(list, err)
}
}
return utilerrors.NewAggregate(list)
}
type SwaggerSchema struct {
api swagger.ApiDeclaration
delegate Schema // For delegating to other api groups
}
func NewSwaggerSchemaFromBytes(data []byte, factory Schema) (Schema, error) {
schema := &SwaggerSchema{}
err := json.Unmarshal(data, &schema.api)
if err != nil {
return nil, err
}
schema.delegate = factory
return schema, nil
}
// validateList unpacks a list and validate every item in the list.
// It return nil if every item is ok.
// Otherwise it return an error list contain errors of every item.
func (s *SwaggerSchema) validateList(obj map[string]interface{}) []error {
items, exists := obj["items"]
if !exists {
return []error{fmt.Errorf("no items field in %#v", obj)}
}
return s.validateItems(items)
}
func (s *SwaggerSchema) validateItems(items interface{}) []error {
allErrs := []error{}
itemList, ok := items.([]interface{})
if !ok {
return append(allErrs, fmt.Errorf("items isn't a slice"))
}
for i, item := range itemList {
fields, ok := item.(map[string]interface{})
if !ok {
allErrs = append(allErrs, fmt.Errorf("items[%d] isn't a map[string]interface{}", i))
continue
}
groupVersion := fields["apiVersion"]
if groupVersion == nil {
allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion not set", i))
continue
}
itemVersion, ok := groupVersion.(string)
if !ok {
allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion isn't string type", i))
continue
}
if len(itemVersion) == 0 {
allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion is empty", i))
}
kind := fields["kind"]
if kind == nil {
allErrs = append(allErrs, fmt.Errorf("items[%d].kind not set", i))
continue
}
itemKind, ok := kind.(string)
if !ok {
allErrs = append(allErrs, fmt.Errorf("items[%d].kind isn't string type", i))
continue
}
if len(itemKind) == 0 {
allErrs = append(allErrs, fmt.Errorf("items[%d].kind is empty", i))
}
version := apiutil.GetVersion(itemVersion)
errs := s.ValidateObject(item, "", version+"."+itemKind)
if len(errs) >= 1 {
allErrs = append(allErrs, errs...)
}
}
return allErrs
}
func (s *SwaggerSchema) ValidateBytes(data []byte) error {
var obj interface{}
out, err := yaml.ToJSON(data)
if err != nil {
return err
}
data = out
if err := json.Unmarshal(data, &obj); err != nil {
return err
}
fields, ok := obj.(map[string]interface{})
if !ok {
return fmt.Errorf("error in unmarshaling data %s", string(data))
}
groupVersion := fields["apiVersion"]
if groupVersion == nil {
return fmt.Errorf("apiVersion not set")
}
if _, ok := groupVersion.(string); !ok {
return fmt.Errorf("apiVersion isn't string type")
}
kind := fields["kind"]
if kind == nil {
return fmt.Errorf("kind not set")
}
if _, ok := kind.(string); !ok {
return fmt.Errorf("kind isn't string type")
}
if strings.HasSuffix(kind.(string), "List") {
return utilerrors.NewAggregate(s.validateList(fields))
}
version := apiutil.GetVersion(groupVersion.(string))
allErrs := s.ValidateObject(obj, "", version+"."+kind.(string))
if len(allErrs) == 1 {
return allErrs[0]
}
return utilerrors.NewAggregate(allErrs)
}
func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName string) []error {
allErrs := []error{}
models := s.api.Models
model, ok := models.At(typeName)
// Verify the api version matches. This is required for nested types with differing api versions because
// s.api only has schema for 1 api version (the parent object type's version).
// e.g. an extensions/v1beta1 Template embedding a /v1 Service requires the schema for the extensions/v1beta1
// api to delegate to the schema for the /v1 api.
// Only do this for !ok objects so that cross ApiVersion vendored types take precedence.
if !ok && s.delegate != nil {
fields, mapOk := obj.(map[string]interface{})
if !mapOk {
return append(allErrs, fmt.Errorf("field %s for %s: expected object of type map[string]interface{}, but the actual type is %T", fieldName, typeName, obj))
}
if delegated, err := s.delegateIfDifferentApiVersion(&unstructured.Unstructured{Object: fields}); delegated {
if err != nil {
allErrs = append(allErrs, err)
}
return allErrs
}
}
if !ok {
return append(allErrs, TypeNotFoundError(typeName))
}
properties := model.Properties
if len(properties.List) == 0 {
// The object does not have any sub-fields.
return nil
}
fields, ok := obj.(map[string]interface{})
if !ok {
return append(allErrs, fmt.Errorf("field %s for %s: expected object of type map[string]interface{}, but the actual type is %T", fieldName, typeName, obj))
}
if len(fieldName) > 0 {
fieldName = fieldName + "."
}
// handle required fields
for _, requiredKey := range model.Required {
if _, ok := fields[requiredKey]; !ok {
allErrs = append(allErrs, fmt.Errorf("field %s%s for %s is required", fieldName, requiredKey, typeName))
}
}
for key, value := range fields {
details, ok := properties.At(key)
// Special case for runtime.RawExtension and runtime.Objects because they always fail to validate
// This is because the actual values will be of some sub-type (e.g. Deployment) not the expected
// super-type (RawExtension)
if s.isGenericArray(details) {
errs := s.validateItems(value)
if len(errs) > 0 {
allErrs = append(allErrs, errs...)
}
continue
}
if !ok {
allErrs = append(allErrs, fmt.Errorf("found invalid field %s for %s", key, typeName))
continue
}
if details.Type == nil && details.Ref == nil {
allErrs = append(allErrs, fmt.Errorf("could not find the type of %s%s from object %v", fieldName, key, details))
}
var fieldType string
if details.Type != nil {
fieldType = *details.Type
} else {
fieldType = *details.Ref
}
if value == nil {
glog.V(2).Infof("Skipping nil field: %s%s", fieldName, key)
continue
}
errs := s.validateField(value, fieldName+key, fieldType, &details)
if len(errs) > 0 {
allErrs = append(allErrs, errs...)
}
}
return allErrs
}
// delegateIfDifferentApiVersion delegates the validation of an object if its ApiGroup does not match the
// current SwaggerSchema.
// First return value is true if the validation was delegated (by a different ApiGroup SwaggerSchema)
// Second return value is the result of the delegated validation if performed.
func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj *unstructured.Unstructured) (bool, error) {
// Never delegate objects in the same ApiVersion or we will get infinite recursion
if !s.isDifferentApiVersion(obj) {
return false, nil
}
// Convert the object back into bytes so that we can pass it to the ValidateBytes function
m, err := json.Marshal(obj.Object)
if err != nil {
return true, err
}
// Delegate validation of this object to the correct SwaggerSchema for its ApiGroup
return true, s.delegate.ValidateBytes(m)
}
// isDifferentApiVersion Returns true if obj lives in a different ApiVersion than the SwaggerSchema does.
// The SwaggerSchema will not be able to process objects in different ApiVersions unless they are vendored.
func (s *SwaggerSchema) isDifferentApiVersion(obj *unstructured.Unstructured) bool {
groupVersion := obj.GetAPIVersion()
return len(groupVersion) > 0 && s.api.ApiVersion != groupVersion
}
// isGenericArray Returns true if p is an array of generic Objects - either RawExtension or Object.
func (s *SwaggerSchema) isGenericArray(p swagger.ModelProperty) bool {
return p.DataTypeFields.Type != nil &&
*p.DataTypeFields.Type == "array" &&
p.Items != nil &&
p.Items.Ref != nil &&
(*p.Items.Ref == "runtime.RawExtension" || *p.Items.Ref == "runtime.Object")
}
// This matches type name in the swagger spec, such as "v1.Binding".
var versionRegexp = regexp.MustCompile(`^(v.+|unversioned|types)\..*`)
func (s *SwaggerSchema) validateField(value interface{}, fieldName, fieldType string, fieldDetails *swagger.ModelProperty) []error {
allErrs := []error{}
if reflect.TypeOf(value) == nil {
return append(allErrs, fmt.Errorf("unexpected nil value for field %v", fieldName))
}
// TODO: caesarxuchao: because we have multiple group/versions and objects
// may reference objects in other group, the commented out way of checking
// if a filedType is a type defined by us is outdated. We use a hacky way
// for now.
// TODO: the type name in the swagger spec is something like "v1.Binding",
// and the "v1" is generated from the package name, not the groupVersion of
// the type. We need to fix go-restful to embed the group name in the type
// name, otherwise we couldn't handle identically named types in different
// groups correctly.
if versionRegexp.MatchString(fieldType) {
// if strings.HasPrefix(fieldType, apiVersion) {
return s.ValidateObject(value, fieldName, fieldType)
}
switch fieldType {
case "string":
// Be loose about what we accept for 'string' since we use IntOrString in a couple of places
_, isString := value.(string)
_, isNumber := value.(float64)
_, isInteger := value.(int)
if !isString && !isNumber && !isInteger {
return append(allErrs, NewInvalidTypeError(reflect.String, reflect.TypeOf(value).Kind(), fieldName))
}
case "array":
arr, ok := value.([]interface{})
if !ok {
return append(allErrs, NewInvalidTypeError(reflect.Array, reflect.TypeOf(value).Kind(), fieldName))
}
var arrType string
if fieldDetails.Items.Ref == nil && fieldDetails.Items.Type == nil {
return append(allErrs, NewInvalidTypeError(reflect.Array, reflect.TypeOf(value).Kind(), fieldName))
}
if fieldDetails.Items.Ref != nil {
arrType = *fieldDetails.Items.Ref
} else {
arrType = *fieldDetails.Items.Type
}
for ix := range arr {
errs := s.validateField(arr[ix], fmt.Sprintf("%s[%d]", fieldName, ix), arrType, nil)
if len(errs) > 0 {
allErrs = append(allErrs, errs...)
}
}
case "uint64":
case "int64":
case "integer":
_, isNumber := value.(float64)
_, isInteger := value.(int)
if !isNumber && !isInteger {
return append(allErrs, NewInvalidTypeError(reflect.Int, reflect.TypeOf(value).Kind(), fieldName))
}
case "float64":
if _, ok := value.(float64); !ok {
return append(allErrs, NewInvalidTypeError(reflect.Float64, reflect.TypeOf(value).Kind(), fieldName))
}
case "boolean":
if _, ok := value.(bool); !ok {
return append(allErrs, NewInvalidTypeError(reflect.Bool, reflect.TypeOf(value).Kind(), fieldName))
}
// API servers before release 1.3 produce swagger spec with `type: "any"` as the fallback type, while newer servers produce spec with `type: "object"`.
// We have both here so that kubectl can work with both old and new api servers.
case "object":
case "any":
default:
return append(allErrs, fmt.Errorf("unexpected type: %v", fieldType))
}
return allErrs
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff