Update godeps

This commit is contained in:
Manuel de Brito Fontes 2016-09-21 20:00:42 -03:00
parent a965f44f84
commit 73e22a50d2
453 changed files with 84778 additions and 70308 deletions

1
vendor/k8s.io/client-go generated vendored
View file

@ -1 +0,0 @@
kubernetes/staging/src/k8s.io/client-go

View file

@ -325,13 +325,13 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource unversion
default:
if code >= 500 {
reason = unversioned.StatusReasonInternalError
message = "an error on the server has prevented the request from succeeding"
message = fmt.Sprintf("an error on the server (%q) has prevented the request from succeeding", serverMessage)
}
}
switch {
case !qualifiedResource.IsEmpty() && len(name) > 0:
case !qualifiedResource.Empty() && len(name) > 0:
message = fmt.Sprintf("%s (%s %s %s)", message, strings.ToLower(verb), qualifiedResource.String(), name)
case !qualifiedResource.IsEmpty():
case !qualifiedResource.Empty():
message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), qualifiedResource.String())
}
var causes []unversioned.StatusCause

View file

@ -30,6 +30,7 @@ import (
"k8s.io/client-go/1.4/pkg/fields"
"k8s.io/client-go/1.4/pkg/labels"
"k8s.io/client-go/1.4/pkg/runtime"
"k8s.io/client-go/1.4/pkg/selection"
"k8s.io/client-go/1.4/pkg/types"
"k8s.io/client-go/1.4/pkg/util/sets"
@ -222,6 +223,10 @@ func IsServiceIPSet(service *Service) bool {
// this function aims to check if the service's cluster IP is requested or not
func IsServiceIPRequested(service *Service) bool {
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
if service.Spec.Type == ServiceTypeExternalName {
return false
}
return service.Spec.ClusterIP == ""
}
@ -379,20 +384,20 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S
}
selector := labels.NewSelector()
for _, expr := range nsm {
var op labels.Operator
var op selection.Operator
switch expr.Operator {
case NodeSelectorOpIn:
op = labels.InOperator
op = selection.In
case NodeSelectorOpNotIn:
op = labels.NotInOperator
op = selection.NotIn
case NodeSelectorOpExists:
op = labels.ExistsOperator
op = selection.Exists
case NodeSelectorOpDoesNotExist:
op = labels.DoesNotExistOperator
op = selection.DoesNotExist
case NodeSelectorOpGt:
op = labels.GreaterThanOperator
op = selection.GreaterThan
case NodeSelectorOpLt:
op = labels.LessThanOperator
op = selection.LessThan
default:
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
}
@ -433,6 +438,20 @@ const (
// 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"
)
// GetAffinityFromPod gets the json serialized affinity data from Pod.Annotations
@ -517,3 +536,51 @@ func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (AvoidPods,
}
return avoidPods, nil
}
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
// SysctlsFromPodAnnotation.
func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) {
safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey])
if err != nil {
return nil, nil, err
}
unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey])
if err != nil {
return nil, nil, err
}
return safe, unsafe, nil
}
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
if len(annotation) == 0 {
return nil, nil
}
kvs := strings.Split(annotation, ",")
sysctls := make([]Sysctl, len(kvs))
for i, kv := range kvs {
cs := strings.Split(kv, "=")
if len(cs) != 2 {
return nil, fmt.Errorf("sysctl %q not of the format sysctl_name=value", kv)
}
sysctls[i].Name = cs[0]
sysctls[i].Value = cs[1]
}
return sysctls, nil
}
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
if len(sysctls) == 0 {
return ""
}
kvs := make([]string, len(sysctls))
for i := range sysctls {
kvs[i] = fmt.Sprintf("%s=%s", sysctls[i].Name, sysctls[i].Value)
}
return strings.Join(kvs, ",")
}

View file

@ -21,6 +21,7 @@ import (
"k8s.io/client-go/1.4/pkg/api/meta"
"k8s.io/client-go/1.4/pkg/api/unversioned"
"k8s.io/client-go/1.4/pkg/runtime"
"k8s.io/client-go/1.4/pkg/util/sets"
)
@ -34,14 +35,21 @@ func RegisterRESTMapper(m meta.RESTMapper) {
RESTMapper = append(RESTMapper.(meta.MultiRESTMapper), m)
}
// Instantiates a DefaultRESTMapper based on types registered in api.Scheme
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper {
return NewDefaultRESTMapperFromScheme(defaultGroupVersions, interfacesFunc, importPathPrefix, ignoredKinds, rootScoped, Scheme)
}
// Instantiates a DefaultRESTMapper based on types registered in the given scheme.
func NewDefaultRESTMapperFromScheme(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *meta.DefaultRESTMapper {
mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc)
// enumerate all supported versions, get the kinds, and register with the mapper how to address
// our resources.
for _, gv := range defaultGroupVersions {
for kind, oType := range Scheme.KnownTypes(gv) {
for kind, oType := range scheme.KnownTypes(gv) {
gvk := gv.WithKind(kind)
// TODO: Remove import path check.
// We check the import path because we currently stuff both "api" and "extensions" objects

View file

@ -131,3 +131,10 @@ func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference
}
meta.OwnerReferences = newReferences
}
func (meta *ObjectMeta) GetClusterName() string {
return meta.ClusterName
}
func (meta *ObjectMeta) SetClusterName(clusterName string) {
meta.ClusterName = clusterName
}

View file

@ -62,6 +62,8 @@ type Object interface {
SetFinalizers(finalizers []string)
GetOwnerReferences() []metatypes.OwnerReference
SetOwnerReferences([]metatypes.OwnerReference)
GetClusterName() string
SetClusterName(clusterName string)
}
var _ Object = &runtime.Unstructured{}
@ -161,16 +163,16 @@ type RESTMapping struct {
// TODO(caesarxuchao): Add proper multi-group support so that kinds & resources are
// scoped to groups. See http://issues.k8s.io/12413 and http://issues.k8s.io/10009.
type RESTMapper interface {
// KindFor takes a partial resource and returns back the single match. Returns an error if there are multiple matches
// KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error)
// KindsFor takes a partial resource and returns back the list of potential kinds in priority order
// KindsFor takes a partial resource and returns the list of potential kinds in priority order
KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error)
// ResourceFor takes a partial resource and returns back the single match. Returns an error if there are multiple matches
// ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
ResourceFor(input unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error)
// ResourcesFor takes a partial resource and returns back the list of potential resource in priority order
// ResourcesFor takes a partial resource and returns the list of potential resource in priority order
ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error)
// RESTMapping identifies a preferred resource mapping for the provided group kind.

View file

@ -183,17 +183,17 @@ func (m *DefaultRESTMapper) ResourceSingularizer(resourceType string) (string, e
if !ok {
continue
}
if singular.IsEmpty() {
if singular.Empty() {
singular = currSingular
continue
}
if currSingular.Resource != singular.Resource {
return resourceType, fmt.Errorf("multiple possibile singular resources (%v) found for %v", resources, resourceType)
return resourceType, fmt.Errorf("multiple possible singular resources (%v) found for %v", resources, resourceType)
}
}
if singular.IsEmpty() {
if singular.Empty() {
return resourceType, fmt.Errorf("no singular of resource %v has been defined", resourceType)
}

View file

@ -0,0 +1,31 @@
/*
Copyright 2016 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 meta
import (
"k8s.io/client-go/1.4/pkg/api/unversioned"
"k8s.io/client-go/1.4/pkg/runtime"
)
// InterfacesForUnstructured returns VersionInterfaces suitable for
// dealing with runtime.Unstructured objects.
func InterfacesForUnstructured(unversioned.GroupVersion) (*VersionInterfaces, error) {
return &VersionInterfaces{
ObjectConvertor: &runtime.UnstructuredObjectConverter{},
MetadataAccessor: NewAccessor(),
}, nil
}

View file

@ -30,7 +30,7 @@ const (
// TODO: to be de!eted after v1.3 is released. PodSpec has a dedicated Subdomain field.
// The annotation value is a string specifying the subdomain e.g. "my-web-service"
// If specified, on the the pod itself, "<hostname>.my-web-service.<namespace>.svc.<cluster domain>" would resolve to
// If specified, on the pod itself, "<hostname>.my-web-service.<namespace>.svc.<cluster domain>" would resolve to
// the pod's IP.
// If there is a headless service named "my-web-service" in the same namespace as the pod, then,
// <hostname>.my-web-service.<namespace>.svc.<cluster domain>" would be resolved by the cluster DNS Server.

View file

@ -45,12 +45,12 @@ var Unversioned = unversioned.GroupVersion{Group: "", Version: "v1"}
// ParameterCodec handles versioning of objects that are converted to query parameters.
var ParameterCodec = runtime.NewParameterCodec(Scheme)
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) unversioned.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
@ -62,7 +62,7 @@ var (
func init() {
// TODO(lavalamp): move this call to scheme builder above. Can't
// remove it from here because lots of people inapropriately rely on it
// remove it from here because lots of people inappropriately rely on it
// (specifically the unversioned time conversion). Can't have it in
// both places because then it gets double registered. Consequence of
// current state is that it only ever gets registered in the main

View file

@ -40,7 +40,8 @@
"secret": null,
"nfs": null,
"iscsi": null,
"glusterfs": null
"glusterfs": null,
"quobyte": null
}
],
"containers": [

View file

@ -93,7 +93,7 @@ func GetPodReadyCondition(status PodStatus) *PodCondition {
}
// GetPodCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the the index of the located condition.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func GetPodCondition(status *PodStatus, conditionType PodConditionType) (int, *PodCondition) {
if status == nil {
return -1, nil
@ -107,7 +107,7 @@ func GetPodCondition(status *PodStatus, conditionType PodConditionType) (int, *P
}
// GetNodeCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the the index of the located condition.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func GetNodeCondition(status *NodeStatus, conditionType NodeConditionType) (int, *NodeCondition) {
if status == nil {
return -1, nil

View file

@ -0,0 +1,89 @@
/*
Copyright 2016 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 service
import (
"strconv"
"github.com/golang/glog"
"k8s.io/client-go/1.4/pkg/api"
)
const (
// 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"
// AnnotationExternalTraffic 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.
AnnotationExternalTraffic = "service.alpha.kubernetes.io/external-traffic"
// AnnotationValueExternalTrafficLocal Value of annotation to specify local endpoints behaviour
AnnotationValueExternalTrafficLocal = "OnlyLocal"
// AnnotationValueExternalTrafficGlobal Value of annotation to specify global (legacy) behaviour
AnnotationValueExternalTrafficGlobal = "Global"
// AnnotationHealthCheckNodePort 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
AnnotationHealthCheckNodePort = "service.alpha.kubernetes.io/healthcheck-nodeport"
)
// NeedsHealthCheck Check service for health check annotations
func NeedsHealthCheck(service *api.Service) bool {
if l, ok := service.Annotations[AnnotationExternalTraffic]; ok {
if l == AnnotationValueExternalTrafficLocal {
return true
} else if l == AnnotationValueExternalTrafficGlobal {
return false
} else {
glog.Errorf("Invalid value for annotation %v", AnnotationExternalTraffic)
return false
}
}
return false
}
// GetServiceHealthCheckNodePort Return health check node port annotation for service, if one exists
func GetServiceHealthCheckNodePort(service *api.Service) int32 {
if NeedsHealthCheck(service) {
if l, ok := service.Annotations[AnnotationHealthCheckNodePort]; ok {
p, err := strconv.Atoi(l)
if err != nil {
glog.Errorf("Failed to parse annotation %v: %v", AnnotationHealthCheckNodePort, err)
return 0
}
return int32(p)
}
}
return 0
}
// GetServiceHealthCheckPathPort Return the path and nodePort programmed into the Cloud LB Health Check
func GetServiceHealthCheckPathPort(service *api.Service) (string, int32) {
if !NeedsHealthCheck(service) {
return "", 0
}
port := GetServiceHealthCheckNodePort(service)
if port == 0 {
return "", 0
}
return "/healthz", port
}

View file

@ -130,7 +130,6 @@ type ObjectMeta struct {
// The prefix is optional. If the prefix is not specified, the key is assumed to be private
// to the user. Other system components that wish to use labels must specify a prefix. The
// "kubernetes.io/" prefix is reserved for use by kubernetes components.
// TODO: replace map[string]string with labels.LabelSet type
Labels map[string]string `json:"labels,omitempty"`
// Annotations are unstructured key value data stored with a resource that may be set by
@ -150,6 +149,11 @@ type ObjectMeta struct {
// from the list. If the deletionTimestamp of the object is non-nil, entries
// in this list can only be removed.
Finalizers []string `json:"finalizers,omitempty"`
// The name of the cluster which the object belongs to.
// This is used to distinguish resources with same name and namespace in different clusters.
// This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
ClusterName string `json:"clusterName,omitempty"`
}
const (
@ -210,8 +214,12 @@ type VolumeSource struct {
PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty"`
// RBD represents a Rados Block Device mount on the host that shares a pod's lifetime
RBD *RBDVolumeSource `json:"rbd,omitempty"`
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty"`
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.
// provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.
FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty"`
// Cinder represents a cinder volume attached and mounted on kubelets host machine
@ -233,6 +241,8 @@ type VolumeSource struct {
ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty"`
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty"`
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty"`
}
// Similar to VolumeSource but meant for the administrator who creates PVs.
@ -255,11 +265,13 @@ type PersistentVolumeSource struct {
NFS *NFSVolumeSource `json:"nfs,omitempty"`
// RBD represents a Rados Block Device mount on the host that shares a pod's lifetime
RBD *RBDVolumeSource `json:"rbd,omitempty"`
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty"`
// ISCSIVolumeSource represents an ISCSI resource that is attached to a
// kubelet's host machine and then exposed to the pod.
ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty"`
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.
// provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.
FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty"`
// Cinder represents a cinder volume attached and mounted on kubelets host machine
Cinder *CinderVolumeSource `json:"cinder,omitempty"`
@ -273,6 +285,8 @@ type PersistentVolumeSource struct {
AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty"`
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty"`
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty"`
}
type PersistentVolumeClaimVolumeSource struct {
@ -516,7 +530,7 @@ type ISCSIVolumeSource struct {
// 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 world wide names (WWNs)
// Required: FC target worldwide names (WWNs)
TargetWWNs []string `json:"targetWWNs"`
// Required: FC target lun number
Lun *int32 `json:"lun"`
@ -531,7 +545,7 @@ type FCVolumeSource struct {
}
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.
// provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.
type FlexVolumeSource struct {
// Driver is the name of the driver to use for this volume.
Driver string `json:"driver"`
@ -555,7 +569,7 @@ type FlexVolumeSource struct {
// Represents a Persistent Disk resource in AWS.
//
// An AWS EBS disk must exist before mounting to a container. The disk
// must also be in the same AWS zone as the kubelet. A AWS EBS disk
// must also be in the same AWS zone as the kubelet. An AWS EBS disk
// can only be mounted as read/write once. AWS EBS volumes support
// ownership management and SELinux relabeling.
type AWSElasticBlockStoreVolumeSource struct {
@ -607,6 +621,12 @@ type SecretVolumeSource struct {
// the volume setup will error. Paths must be relative and may not contain
// the '..' path or start with '..'.
Items []KeyToPath `json:"items,omitempty"`
// Mode bits to use on created files by default. Must be a value between
// 0 and 0777.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
DefaultMode *int32 `json:"defaultMode,omitempty"`
}
// Represents an NFS mount that lasts the lifetime of a pod.
@ -623,6 +643,30 @@ type NFSVolumeSource struct {
ReadOnly bool `json:"readOnly,omitempty"`
}
// Represents a Quobyte mount that lasts the lifetime of a pod.
// Quobyte volumes do not support ownership management or SELinux relabeling.
type QuobyteVolumeSource struct {
// Registry represents a single or multiple Quobyte Registry services
// specified as a string as host:port pair (multiple entries are separated with commas)
// which acts as the central registry for volumes
Registry string `json:"registry"`
// Volume is a string that references an already created Quobyte volume by name.
Volume string `json:"volume"`
// Defaults to false (read/write). ReadOnly here will force
// the Quobyte to be mounted with read-only permissions
ReadOnly bool `json:"readOnly,omitempty"`
// User to map volume access to
// Defaults to the root user
User string `json:"user,omitempty"`
// Group to map volume access to
// Default is no group
Group string `json:"group,omitempty"`
}
// Represents a Glusterfs mount that lasts the lifetime of a pod.
// Glusterfs volumes do not support ownership management or SELinux relabeling.
type GlusterfsVolumeSource struct {
@ -708,6 +752,12 @@ type FlockerVolumeSource struct {
type DownwardAPIVolumeSource struct {
// Items is a list of DownwardAPIVolume file
Items []DownwardAPIVolumeFile `json:"items,omitempty"`
// Mode bits to use on created files by default. Must be a value between
// 0 and 0777.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
DefaultMode *int32 `json:"defaultMode,omitempty"`
}
// Represents a single file containing information from the downward API
@ -719,6 +769,11 @@ type DownwardAPIVolumeFile struct {
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty"`
// Optional: mode bits to use on this file, must be a value between 0
// and 0777. If not specified, the volume defaultMode will be used.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
Mode *int32 `json:"mode,omitempty"`
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
@ -742,6 +797,31 @@ type VsphereVirtualDiskVolumeSource struct {
FSType string `json:"fsType,omitempty"`
}
type AzureDataDiskCachingMode string
const (
AzureDataDiskCachingNone AzureDataDiskCachingMode = "None"
AzureDataDiskCachingReadOnly AzureDataDiskCachingMode = "ReadOnly"
AzureDataDiskCachingReadWrite AzureDataDiskCachingMode = "ReadWrite"
)
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
type AzureDiskVolumeSource struct {
// The Name of the data disk in the blob storage
DiskName string `json:"diskName"`
// The URI the the data disk in the blob storage
DataDiskURI string `json:"diskURI"`
// Host Caching mode: None, Read Only, Read Write.
CachingMode *AzureDataDiskCachingMode `json:"cachingMode,omitempty"`
// Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
FSType *string `json:"fsType,omitempty"`
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
ReadOnly *bool `json:"readOnly,omitempty"`
}
// Adapts a ConfigMap into a volume.
//
// The contents of the target ConfigMap's Data field will be presented in a
@ -758,6 +838,12 @@ type ConfigMapVolumeSource struct {
// the volume setup will error. Paths must be relative and may not contain
// the '..' path or start with '..'.
Items []KeyToPath `json:"items,omitempty"`
// Mode bits to use on created files by default. Must be a value between
// 0 and 0777.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
DefaultMode *int32 `json:"defaultMode,omitempty"`
}
// Maps a string key to a path within a volume.
@ -770,6 +856,11 @@ type KeyToPath struct {
// May not contain the path element '..'.
// May not start with the string '..'.
Path string `json:"path"`
// Optional: mode bits to use on this file, should be a value between 0
// and 0777. If not specified, the volume defaultMode will be used.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
Mode *int32 `json:"mode,omitempty"`
}
// ContainerPort represents a network port in a single container
@ -821,7 +912,8 @@ type EnvVar struct {
// EnvVarSource represents a source for the value of an EnvVar.
// Only one of its fields may be set.
type EnvVarSource struct {
// Selects a field of the pod; only name and namespace are supported.
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
// spec.nodeName, spec.serviceAccountName, status.podIP.
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
@ -1472,6 +1564,14 @@ type PodSpec struct {
Subdomain string `json:"subdomain,omitempty"`
}
// Sysctl defines a kernel parameter to be set
type Sysctl struct {
// Name of a property to set
Name string `json:"name"`
// Value of a property to set
Value string `json:"value"`
}
// PodSecurityContext holds pod-level security attributes and common container settings.
// Some fields are also present in container.securityContext. Field values of
// container.securityContext take precedence over field values of PodSecurityContext.
@ -1636,6 +1736,9 @@ type ReplicationControllerStatus struct {
// The number of pods that have labels matching the labels of the pod template of the replication controller.
FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"`
// The number of ready replicas for this replication controller.
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
// ObservedGeneration is the most recent generation observed by the controller.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}
@ -1704,6 +1807,11 @@ const (
// external load balancer (if the cloud provider supports it), in addition
// to 'NodePort' type.
ServiceTypeLoadBalancer ServiceType = "LoadBalancer"
// ServiceTypeExternalName means a service consists of only a reference to
// an external name that kubedns or equivalent will return as a CNAME
// record, with no exposing or proxying of any pods involved.
ServiceTypeExternalName ServiceType = "ExternalName"
)
// ServiceStatus represents the current status of a service
@ -1734,24 +1842,49 @@ type LoadBalancerIngress struct {
// ServiceSpec describes the attributes that a user creates on a service
type ServiceSpec struct {
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
// Type determines how the Service is exposed. Defaults to ClusterIP. Valid
// options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to
// endpoints. Endpoints are determined by the selector or if that is not
// specified, by manual construction of an Endpoints object. If clusterIP is
// "None", no virtual IP is allocated and the endpoints are published as a
// set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which
// routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an
// external load-balancer (if supported in the current cloud) which routes
// to the clusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Type ServiceType `json:"type,omitempty"`
// Required: The list of ports that are exposed by this service.
Ports []ServicePort `json:"ports"`
// This service will route traffic to pods having labels matching this selector. If empty or not present,
// the service is assumed to have endpoints set by an external process and Kubernetes will not modify
// those endpoints.
// Route service traffic to pods with label keys and values matching this
// selector. If empty or not present, the service is assumed to have an
// external process managing its endpoints, which Kubernetes will not
// modify. Only applies to types ClusterIP, NodePort, and LoadBalancer.
// Ignored if type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Selector map[string]string `json:"selector"`
// ClusterIP is usually assigned by the master. If specified by the user
// we will try to respect it or else fail the request. This field can
// not be changed by updates.
// Valid values are None, empty string (""), or a valid IP address
// None can be specified for headless services when proxying is not required
// ClusterIP is the IP address of the service and is usually assigned
// randomly by the master. If an address is specified manually and is not in
// use by others, it will be allocated to the service; otherwise, creation
// of the service will fail. This field can not be changed through updates.
// Valid values are "None", empty string (""), or a valid IP address. "None"
// can be specified for headless services when proxying is not required.
// Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
// type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
ClusterIP string `json:"clusterIP,omitempty"`
// ExternalName is the external reference that kubedns or equivalent will
// return as a CNAME record for this service. No proxying will be involved.
// Must be a valid DNS name and requires Type to be ExternalName.
ExternalName string
// ExternalIPs are used by external load balancers, or can be set by
// users to handle external traffic that arrives at a node.
ExternalIPs []string `json:"externalIPs,omitempty"`
@ -1889,6 +2022,8 @@ type EndpointAddress struct {
// Optional: Hostname of this endpoint
// Meant to be used by DNS servers etc.
Hostname string `json:"hostname,omitempty"`
// Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.
NodeName *string `json:"nodeName,omitempty"`
// Optional: The kubernetes object related to the entry point.
TargetRef *ObjectReference
}

View file

@ -50,7 +50,7 @@ func (gr GroupResource) WithVersion(version string) GroupVersionResource {
return GroupVersionResource{Group: gr.Group, Version: version, Resource: gr.Resource}
}
func (gr GroupResource) IsEmpty() bool {
func (gr GroupResource) Empty() bool {
return len(gr.Group) == 0 && len(gr.Resource) == 0
}
@ -81,7 +81,7 @@ type GroupVersionResource struct {
Resource string `protobuf:"bytes,3,opt,name=resource"`
}
func (gvr GroupVersionResource) IsEmpty() bool {
func (gvr GroupVersionResource) Empty() bool {
return len(gvr.Group) == 0 && len(gvr.Version) == 0 && len(gvr.Resource) == 0
}
@ -106,7 +106,7 @@ type GroupKind struct {
Kind string `protobuf:"bytes,2,opt,name=kind"`
}
func (gk GroupKind) IsEmpty() bool {
func (gk GroupKind) Empty() bool {
return len(gk.Group) == 0 && len(gk.Kind) == 0
}
@ -131,8 +131,8 @@ type GroupVersionKind struct {
Kind string `protobuf:"bytes,3,opt,name=kind"`
}
// IsEmpty returns true if group, version, and kind are empty
func (gvk GroupVersionKind) IsEmpty() bool {
// Empty returns true if group, version, and kind are empty
func (gvk GroupVersionKind) Empty() bool {
return len(gvk.Group) == 0 && len(gvk.Version) == 0 && len(gvk.Kind) == 0
}
@ -156,8 +156,8 @@ type GroupVersion struct {
Version string `protobuf:"bytes,2,opt,name=version"`
}
// IsEmpty returns true if group and version are empty
func (gv GroupVersion) IsEmpty() bool {
// Empty returns true if group and version are empty
func (gv GroupVersion) Empty() bool {
return len(gv.Group) == 0 && len(gv.Version) == 0
}
@ -165,7 +165,7 @@ func (gv GroupVersion) IsEmpty() bool {
// it returns "v1".
func (gv GroupVersion) String() string {
// special case the internal apiVersion for the legacy kube types
if gv.IsEmpty() {
if gv.Empty() {
return ""
}
@ -179,6 +179,25 @@ func (gv GroupVersion) String() string {
return gv.Version
}
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
// if none of the options match the group. It prefers a match to group and version over just group.
// TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme.
// TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
// in fewer places.
func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
for _, gvk := range kinds {
if gvk.Group == gv.Group && gvk.Version == gv.Version {
return gvk, true
}
}
for _, gvk := range kinds {
if gvk.Group == gv.Group {
return gv.WithKind(gvk.Kind), true
}
}
return GroupVersionKind{}, false
}
// ParseGroupVersion turns "group/version" string into a GroupVersion struct. It reports error
// if it cannot parse the string.
func ParseGroupVersion(gv string) (GroupVersion, error) {
@ -241,6 +260,25 @@ func (gv *GroupVersion) UnmarshalText(value []byte) error {
return gv.unmarshal(value)
}
// GroupVersions can be used to represent a set of desired group versions.
// TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme.
// TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
// in fewer places.
type GroupVersions []GroupVersion
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
// if none of the options match the group.
func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
for _, gv := range gvs {
target, ok := gv.KindForGroupVersionKinds(kinds)
if !ok {
continue
}
return target, true
}
return GroupVersionKind{}, false
}
// ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that
// do not use TypeMeta.
func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) {

View file

@ -20,6 +20,7 @@ import (
"fmt"
"k8s.io/client-go/1.4/pkg/labels"
"k8s.io/client-go/1.4/pkg/selection"
"k8s.io/client-go/1.4/pkg/util/sets"
)
@ -35,23 +36,23 @@ func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
}
selector := labels.NewSelector()
for k, v := range ps.MatchLabels {
r, err := labels.NewRequirement(k, labels.EqualsOperator, sets.NewString(v))
r, err := labels.NewRequirement(k, selection.Equals, sets.NewString(v))
if err != nil {
return nil, err
}
selector = selector.Add(*r)
}
for _, expr := range ps.MatchExpressions {
var op labels.Operator
var op selection.Operator
switch expr.Operator {
case LabelSelectorOpIn:
op = labels.InOperator
op = selection.In
case LabelSelectorOpNotIn:
op = labels.NotInOperator
op = selection.NotIn
case LabelSelectorOpExists:
op = labels.ExistsOperator
op = selection.Exists
case LabelSelectorOpDoesNotExist:
op = labels.DoesNotExistOperator
op = selection.DoesNotExist
default:
return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
}
@ -108,7 +109,7 @@ func ParseToLabelSelector(selector string) (*LabelSelector, error) {
for _, req := range reqs {
var op LabelSelectorOperator
switch req.Operator() {
case labels.EqualsOperator, labels.DoubleEqualsOperator:
case selection.Equals, selection.DoubleEquals:
vals := req.Values()
if vals.Len() != 1 {
return nil, fmt.Errorf("equals operator must have exactly one value")
@ -119,15 +120,15 @@ func ParseToLabelSelector(selector string) (*LabelSelector, error) {
}
labelSelector.MatchLabels[req.Key()] = val
continue
case labels.InOperator:
case selection.In:
op = LabelSelectorOpIn
case labels.NotInOperator:
case selection.NotIn:
op = LabelSelectorOpNotIn
case labels.ExistsOperator:
case selection.Exists:
op = LabelSelectorOpExists
case labels.DoesNotExistOperator:
case selection.DoesNotExist:
op = LabelSelectorOpDoesNotExist
case labels.GreaterThanOperator, labels.LessThanOperator:
case selection.GreaterThan, selection.LessThan:
// Adding a separate case for these operators to indicate that this is deliberate
return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator())
default:

View file

@ -19,7 +19,7 @@ package unversioned
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = GroupVersion{Group: "", Version: ""}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

View file

@ -164,7 +164,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
}
// Add field label conversions for kinds having selectable nothing but ObjectMeta fields.
for _, kind := range []string{
for _, k := range []string{
"Endpoints",
"ResourceQuota",
"PersistentVolumeClaim",
@ -172,7 +172,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
"ServiceAccount",
"ConfigMap",
} {
err = api.Scheme.AddFieldLabelConversionFunc("v1", kind,
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",
@ -189,17 +190,18 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
}
// Add field conversion funcs.
err = api.Scheme.AddFieldLabelConversionFunc("v1", "Pod",
err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
func(label, value string) (string, string, error) {
switch label {
case "metadata.name",
"metadata.namespace",
case "metadata.annotations",
"metadata.labels",
"metadata.annotations",
"status.phase",
"status.podIP",
"metadata.name",
"metadata.namespace",
"spec.nodeName",
"spec.restartPolicy":
"spec.restartPolicy",
"spec.serviceAccountName",
"status.phase",
"status.podIP":
return label, value, nil
// This is for backwards compatibility with old v1 clients which send spec.host
case "spec.host":
@ -212,7 +214,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
if err != nil {
return err
}
err = api.Scheme.AddFieldLabelConversionFunc("v1", "Node",
err = scheme.AddFieldLabelConversionFunc("v1", "Node",
func(label, value string) (string, string, error) {
switch label {
case "metadata.name":
@ -227,7 +229,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
if err != nil {
return err
}
err = api.Scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
err = scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
func(label, value string) (string, string, error) {
switch label {
case "metadata.name",
@ -241,45 +243,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
if err != nil {
return err
}
err = api.Scheme.AddFieldLabelConversionFunc("v1", "Event",
func(label, value string) (string, string, error) {
switch label {
case "involvedObject.kind",
"involvedObject.namespace",
"involvedObject.name",
"involvedObject.uid",
"involvedObject.apiVersion",
"involvedObject.resourceVersion",
"involvedObject.fieldPath",
"reason",
"source",
"type",
"metadata.namespace",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
},
)
if err != nil {
return err
}
err = api.Scheme.AddFieldLabelConversionFunc("v1", "Namespace",
func(label, value string) (string, string, error) {
switch label {
case "status.phase",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
},
)
if err != nil {
return err
}
err = api.Scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
err = scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
func(label, value string) (string, string, error) {
switch label {
case "metadata.name":
@ -292,19 +256,13 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
if err != nil {
return err
}
err = api.Scheme.AddFieldLabelConversionFunc("v1", "Secret",
func(label, value string) (string, string, error) {
switch label {
case "type",
"metadata.namespace",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
},
)
if err != nil {
if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
return err
}
if err := AddFieldLabelConversionsForNamespace(scheme); err != nil {
return err
}
if err := AddFieldLabelConversionsForSecret(scheme); err != nil {
return err
}
return nil
@ -463,7 +421,7 @@ func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult,
}
func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error {
// TODO: when we move init container to beta, remove these conversions
// TODO: sometime after we move init container to stable, remove these conversions
if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
var values []ContainerStatus
if err := json.Unmarshal([]byte(value), &values); err != nil {
@ -497,7 +455,7 @@ func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec,
return err
}
// TODO: when we move init container to beta, remove these conversions
// 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 {
@ -513,14 +471,22 @@ func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec,
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: when we move init container to beta, remove these conversions
// 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 {
@ -545,6 +511,7 @@ func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
}
return nil
}
@ -598,7 +565,7 @@ func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error
return err
}
// TODO: when we move init container to beta, remove these conversions
// 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))
@ -606,6 +573,7 @@ func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
}
if len(out.Spec.InitContainers) > 0 {
@ -614,6 +582,7 @@ func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error
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)
@ -638,7 +607,13 @@ func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error
}
func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error {
// TODO: when we move init container to beta, 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
}
// 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 {
@ -676,6 +651,7 @@ func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error
out.Annotations[k] = v
}
delete(out.Annotations, PodInitContainersAnnotationKey)
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
}
return nil
@ -769,3 +745,53 @@ func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.Reso
}
return nil
}
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
return scheme.AddFieldLabelConversionFunc("v1", "Event",
func(label, value string) (string, string, error) {
switch label {
case "involvedObject.kind",
"involvedObject.namespace",
"involvedObject.name",
"involvedObject.uid",
"involvedObject.apiVersion",
"involvedObject.resourceVersion",
"involvedObject.fieldPath",
"reason",
"source",
"type",
"metadata.namespace",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
})
}
func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error {
return scheme.AddFieldLabelConversionFunc("v1", "Namespace",
func(label, value string) (string, string, error) {
switch label {
case "status.phase",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
})
}
func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
return scheme.AddFieldLabelConversionFunc("v1", "Secret",
func(label, value string) (string, string, error) {
switch label {
case "type",
"metadata.namespace",
"metadata.name":
return label, value, nil
default:
return "", "", fmt.Errorf("field label not supported: %s", label)
}
})
}

View file

@ -35,6 +35,9 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
SetDefaults_Pod,
SetDefaults_PodSpec,
SetDefaults_Probe,
SetDefaults_SecretVolumeSource,
SetDefaults_ConfigMapVolumeSource,
SetDefaults_DownwardAPIVolumeSource,
SetDefaults_Secret,
SetDefaults_PersistentVolume,
SetDefaults_PersistentVolumeClaim,
@ -174,6 +177,24 @@ func SetDefaults_Probe(obj *Probe) {
obj.FailureThreshold = 3
}
}
func SetDefaults_SecretVolumeSource(obj *SecretVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(SecretVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_ConfigMapVolumeSource(obj *ConfigMapVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(ConfigMapVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_DownwardAPIVolumeSource(obj *DownwardAPIVolumeSource) {
if obj.DefaultMode == nil {
perm := int32(DownwardAPIVolumeSourceDefaultMode)
obj.DefaultMode = &perm
}
}
func SetDefaults_Secret(obj *Secret) {
if obj.Type == "" {
obj.Type = SecretTypeOpaque
@ -197,6 +218,20 @@ func SetDefaults_ISCSIVolumeSource(obj *ISCSIVolumeSource) {
obj.ISCSIInterface = "default"
}
}
func SetDefaults_AzureDiskVolumeSource(obj *AzureDiskVolumeSource) {
if obj.CachingMode == nil {
obj.CachingMode = new(AzureDataDiskCachingMode)
*obj.CachingMode = AzureDataDiskCachingNone
}
if obj.FSType == nil {
obj.FSType = new(string)
*obj.FSType = "ext4"
}
if obj.ReadOnly == nil {
obj.ReadOnly = new(bool)
*obj.ReadOnly = false
}
}
func SetDefaults_Endpoints(obj *Endpoints) {
for i := range obj.Subsets {
ss := &obj.Subsets[i]

View file

@ -89,6 +89,27 @@ message AvoidPods {
repeated PreferAvoidPodsEntry preferAvoidPods = 1;
}
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
message AzureDiskVolumeSource {
// The Name of the data disk in the blob storage
optional string diskName = 1;
// The URI the data disk in the blob storage
optional string diskURI = 2;
// Host Caching mode: None, Read Only, Read Write.
optional string cachingMode = 3;
// Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
optional string fsType = 4;
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
optional bool readOnly = 5;
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
message AzureFileVolumeSource {
// the name of secret that contains Azure Storage Account Name and Key
@ -256,6 +277,13 @@ message ConfigMapVolumeSource {
// the volume setup will error. Paths must be relative and may not contain
// the '..' path or start with '..'.
repeated KeyToPath items = 2;
// Optional: mode bits to use on created files by default. Must be a
// value between 0 and 0777. Defaults to 0644.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
optional int32 defaultMode = 3;
}
// A single application container that you want to run within a pod.
@ -526,6 +554,12 @@ message DownwardAPIVolumeFile {
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
optional ResourceFieldSelector resourceFieldRef = 3;
// Optional: mode bits to use on this file, must be a value between 0
// and 0777. If not specified, the volume defaultMode will be used.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
optional int32 mode = 4;
}
// DownwardAPIVolumeSource represents a volume containing downward API info.
@ -533,6 +567,13 @@ message DownwardAPIVolumeFile {
message DownwardAPIVolumeSource {
// Items is a list of downward API volume file
repeated DownwardAPIVolumeFile items = 1;
// Optional: mode bits to use on created files by default. Must be a
// value between 0 and 0777. Defaults to 0644.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
optional int32 defaultMode = 2;
}
// Represents an empty directory for a pod.
@ -558,6 +599,9 @@ message EndpointAddress {
// The Hostname of this endpoint
optional string hostname = 3;
// Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.
optional string nodeName = 4;
// Reference to object providing the endpoint.
optional ObjectReference targetRef = 2;
}
@ -660,7 +704,8 @@ message EnvVar {
// EnvVarSource represents a source for the value of an EnvVar.
message EnvVarSource {
// Selects a field of the pod; only name and namespace are supported.
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
// spec.nodeName, spec.serviceAccountName, status.podIP.
optional ObjectFieldSelector fieldRef = 1;
// Selects a resource of the container: only resources limits and requests
@ -751,7 +796,7 @@ message ExportOptions {
// Fibre Channel volumes can only be mounted as read/write once.
// Fibre Channel volumes support ownership management and SELinux relabeling.
message FCVolumeSource {
// Required: FC target world wide names (WWNs)
// Required: FC target worldwide names (WWNs)
repeated string targetWWNs = 1;
// Required: FC target lun number
@ -769,7 +814,7 @@ message FCVolumeSource {
}
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.
// provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.
message FlexVolumeSource {
// Driver is the name of the driver to use for this volume.
optional string driver = 1;
@ -960,6 +1005,12 @@ message KeyToPath {
// May not contain the path element '..'.
// May not start with the string '..'.
optional string path = 2;
// Optional: mode bits to use on this file, must be a value between 0
// and 0777. If not specified, the volume defaultMode will be used.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
optional int32 mode = 3;
}
// Lifecycle describes actions that the management system should take in response to container lifecycle
@ -1197,7 +1248,7 @@ message NodeAffinity {
repeated PreferredSchedulingTerm preferredDuringSchedulingIgnoredDuringExecution = 2;
}
// NodeCondition contains condition infromation for a node.
// NodeCondition contains condition information for a node.
message NodeCondition {
// Type of node condition.
optional string type = 1;
@ -1301,6 +1352,7 @@ message NodeStatus {
// NodePhase is the recently observed lifecycle phase of the node.
// More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase
// The field is never populated, and now is deprecated.
optional string phase = 3;
// Conditions is an array of current observed node conditions.
@ -1475,7 +1527,6 @@ message ObjectMeta {
// (scope and select) objects. May match selectors of replication controllers
// and services.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md
// TODO: replace map[string]string with labels.LabelSet type
map<string, string> labels = 11;
// Annotations is an unstructured key value map stored with a resource that may be
@ -1495,6 +1546,11 @@ message ObjectMeta {
// from the list. If the deletionTimestamp of the object is non-nil, entries
// in this list can only be removed.
repeated string finalizers = 14;
// The name of the cluster which the object belongs to.
// This is used to distinguish resources with same name and namespace in different clusters.
// This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
optional string clusterName = 15;
}
// ObjectReference contains enough information to let you inspect or modify the referred object.
@ -1710,7 +1766,7 @@ message PersistentVolumeSource {
optional FlockerVolumeSource flocker = 11;
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an
// provisioned/attached using an exec based plugin. This is an
// alpha feature and may change in future.
optional FlexVolumeSource flexVolume = 12;
@ -1719,6 +1775,12 @@ message PersistentVolumeSource {
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
optional VsphereVirtualDiskVolumeSource vsphereVolume = 14;
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
optional QuobyteVolumeSource quobyte = 15;
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
optional AzureDiskVolumeSource azureDisk = 16;
}
// PersistentVolumeSpec is the specification of a persistent volume.
@ -1742,7 +1804,7 @@ message PersistentVolumeSpec {
// What happens to a persistent volume when released from its claim.
// Valid options are Retain (default) and Recycle.
// Recyling must be supported by the volume plugin underlying this persistent volume.
// Recycling must be supported by the volume plugin underlying this persistent volume.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#recycling-policy
optional string persistentVolumeReclaimPolicy = 5;
}
@ -2288,6 +2350,30 @@ message Probe {
optional int32 failureThreshold = 6;
}
// Represents a Quobyte mount that lasts the lifetime of a pod.
// Quobyte volumes do not support ownership management or SELinux relabeling.
message QuobyteVolumeSource {
// Registry represents a single or multiple Quobyte Registry services
// specified as a string as host:port pair (multiple entries are separated with commas)
// which acts as the central registry for volumes
optional string registry = 1;
// Volume is a string that references an already created Quobyte volume by name.
optional string volume = 2;
// ReadOnly here will force the Quobyte volume to be mounted with read-only permissions.
// Defaults to false.
optional bool readOnly = 3;
// User to map volume access to
// Defaults to serivceaccount user
optional string user = 4;
// Group to map volume access to
// Default is no group
optional string group = 5;
}
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
// RBD volumes support ownership management and SELinux relabeling.
message RBDVolumeSource {
@ -2407,6 +2493,9 @@ message ReplicationControllerStatus {
// The number of pods that have labels matching the labels of the pod template of the replication controller.
optional int32 fullyLabeledReplicas = 2;
// The number of ready replicas for this replication controller.
optional int32 readyReplicas = 4;
// ObservedGeneration reflects the generation of the most recently observed replication controller.
optional int64 observedGeneration = 3;
}
@ -2473,13 +2562,13 @@ message ResourceQuotaStatus {
// ResourceRequirements describes the compute resource requirements.
message ResourceRequirements {
// Limits describes the maximum amount of compute resources allowed.
// More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications
// More info: http://kubernetes.io/docs/user-guide/compute-resources/
map<string, k8s.io.kubernetes.pkg.api.resource.Quantity> limits = 1;
// Requests describes the minimum amount of compute resources required.
// If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
// otherwise to an implementation-defined value.
// More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications
// More info: http://kubernetes.io/docs/user-guide/compute-resources/
map<string, k8s.io.kubernetes.pkg.api.resource.Quantity> requests = 2;
}
@ -2561,6 +2650,13 @@ message SecretVolumeSource {
// the volume setup will error. Paths must be relative and may not contain
// the '..' path or start with '..'.
repeated KeyToPath items = 2;
// Optional: mode bits to use on created files by default. Must be a
// value between 0 and 0777. Defaults to 0644.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
optional int32 defaultMode = 3;
}
// SecurityContext holds security configuration that will be applied to a container.
@ -2716,24 +2812,39 @@ message ServiceSpec {
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
repeated ServicePort ports = 1;
// This service will route traffic to pods having labels matching this selector.
// Label keys and values that must match in order to receive traffic for this service.
// If not specified, endpoints must be manually specified and the system will not automatically manage them.
// Route service traffic to pods with label keys and values matching this
// selector. If empty or not present, the service is assumed to have an
// external process managing its endpoints, which Kubernetes will not
// modify. Only applies to types ClusterIP, NodePort, and LoadBalancer.
// Ignored if type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
map<string, string> selector = 2;
// ClusterIP is usually assigned by the master and is the IP address of the service.
// If specified, it will be allocated to the service if it is unused
// or else creation of the service will fail.
// Valid values are None, empty string (""), or a valid IP address.
// 'None' can be specified for a headless service when proxying is not required.
// Cannot be updated.
// clusterIP is the IP address of the service and is usually assigned
// randomly by the master. If an address is specified manually and is not in
// use by others, it will be allocated to the service; otherwise, creation
// of the service will fail. This field can not be changed through updates.
// Valid values are "None", empty string (""), or a valid IP address. "None"
// can be specified for headless services when proxying is not required.
// Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
// type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
optional string clusterIP = 3;
// Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer.
// Defaults to ClusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services
// type determines how the Service is exposed. Defaults to ClusterIP. Valid
// options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to
// endpoints. Endpoints are determined by the selector or if that is not
// specified, by manual construction of an Endpoints object. If clusterIP is
// "None", no virtual IP is allocated and the endpoints are published as a
// set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which
// routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an
// external load-balancer (if supported in the current cloud) which routes
// to the clusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
optional string type = 4;
// externalIPs is a list of IP addresses for which nodes in the cluster
@ -2772,6 +2883,11 @@ message ServiceSpec {
// cloud-provider does not support the feature."
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md
repeated string loadBalancerSourceRanges = 9;
// externalName is the external reference that kubedns or equivalent will
// return as a CNAME record for this service. No proxying will be involved.
// Must be a valid DNS name and requires Type to be ExternalName.
optional string externalName = 10;
}
// ServiceStatus represents the current status of a service.
@ -2913,7 +3029,7 @@ message VolumeSource {
optional RBDVolumeSource rbd = 11;
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an
// provisioned/attached using an exec based plugin. This is an
// alpha feature and may change in future.
optional FlexVolumeSource flexVolume = 12;
@ -2941,6 +3057,12 @@ message VolumeSource {
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
optional VsphereVirtualDiskVolumeSource vsphereVolume = 20;
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
optional QuobyteVolumeSource quobyte = 21;
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
optional AzureDiskVolumeSource azureDisk = 22;
}
// Represents a vSphere volume resource.

View file

@ -83,3 +83,10 @@ func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference
}
meta.OwnerReferences = newReferences
}
func (meta *ObjectMeta) GetClusterName() string {
return meta.ClusterName
}
func (meta *ObjectMeta) SetClusterName(clusterName string) {
meta.ClusterName = clusterName
}

View file

@ -167,7 +167,6 @@ type ObjectMeta struct {
// (scope and select) objects. May match selectors of replication controllers
// and services.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md
// TODO: replace map[string]string with labels.LabelSet type
Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`
// Annotations is an unstructured key value map stored with a resource that may be
@ -187,6 +186,11 @@ type ObjectMeta struct {
// from the list. If the deletionTimestamp of the object is non-nil, entries
// in this list can only be removed.
Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`
// The name of the cluster which the object belongs to.
// This is used to distinguish resources with same name and namespace in different clusters.
// This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"`
}
const (
@ -254,19 +258,16 @@ type VolumeSource struct {
// More info: http://releases.k8s.io/HEAD/examples/volumes/rbd/README.md
RBD *RBDVolumeSource `json:"rbd,omitempty" protobuf:"bytes,11,opt,name=rbd"`
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an
// provisioned/attached using an exec based plugin. This is an
// alpha feature and may change in future.
FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" protobuf:"bytes,12,opt,name=flexVolume"`
// Cinder represents a cinder volume attached and mounted on kubelets host machine
// More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md
Cinder *CinderVolumeSource `json:"cinder,omitempty" protobuf:"bytes,13,opt,name=cinder"`
// CephFS represents a Ceph FS mount on the host that shares a pod's lifetime
CephFS *CephFSVolumeSource `json:"cephfs,omitempty" protobuf:"bytes,14,opt,name=cephfs"`
// Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running
Flocker *FlockerVolumeSource `json:"flocker,omitempty" protobuf:"bytes,15,opt,name=flocker"`
// DownwardAPI represents downward API about the pod that should populate this volume
DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty" protobuf:"bytes,16,opt,name=downwardAPI"`
// FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.
@ -277,6 +278,10 @@ type VolumeSource struct {
ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty" protobuf:"bytes,19,opt,name=configMap"`
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" protobuf:"bytes,20,opt,name=vsphereVolume"`
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" protobuf:"bytes,21,opt,name=quobyte"`
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" protobuf:"bytes,22,opt,name=azureDisk"`
}
// PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace.
@ -332,13 +337,17 @@ type PersistentVolumeSource struct {
// Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running
Flocker *FlockerVolumeSource `json:"flocker,omitempty" protobuf:"bytes,11,opt,name=flocker"`
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an
// provisioned/attached using an exec based plugin. This is an
// alpha feature and may change in future.
FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" protobuf:"bytes,12,opt,name=flexVolume"`
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,13,opt,name=azureFile"`
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" protobuf:"bytes,14,opt,name=vsphereVolume"`
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" protobuf:"bytes,15,opt,name=quobyte"`
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" protobuf:"bytes,16,opt,name=azureDisk"`
}
// +genclient=true
@ -382,7 +391,7 @@ type PersistentVolumeSpec struct {
ClaimRef *ObjectReference `json:"claimRef,omitempty" protobuf:"bytes,4,opt,name=claimRef"`
// What happens to a persistent volume when released from its claim.
// Valid options are Retain (default) and Recycle.
// Recyling must be supported by the volume plugin underlying this persistent volume.
// Recycling must be supported by the volume plugin underlying this persistent volume.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#recycling-policy
PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty" protobuf:"bytes,5,opt,name=persistentVolumeReclaimPolicy,casttype=PersistentVolumeReclaimPolicy"`
}
@ -425,6 +434,8 @@ type PersistentVolumeList struct {
Items []PersistentVolume `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// +genclient=true
// PersistentVolumeClaim is a user's request for and claim to a persistent volume
type PersistentVolumeClaim struct {
unversioned.TypeMeta `json:",inline"`
@ -689,8 +700,32 @@ type GCEPersistentDiskVolumeSource struct {
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,4,opt,name=readOnly"`
}
// Represents a Quobyte mount that lasts the lifetime of a pod.
// Quobyte volumes do not support ownership management or SELinux relabeling.
type QuobyteVolumeSource struct {
// Registry represents a single or multiple Quobyte Registry services
// specified as a string as host:port pair (multiple entries are separated with commas)
// which acts as the central registry for volumes
Registry string `json:"registry" protobuf:"bytes,1,opt,name=registry"`
// Volume is a string that references an already created Quobyte volume by name.
Volume string `json:"volume" protobuf:"bytes,2,opt,name=volume"`
// ReadOnly here will force the Quobyte volume to be mounted with read-only permissions.
// Defaults to false.
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,3,opt,name=readOnly"`
// User to map volume access to
// Defaults to serivceaccount user
User string `json:"user,omitempty" protobuf:"bytes,4,opt,name=user"`
// Group to map volume access to
// Default is no group
Group string `json:"group,omitempty" protobuf:"bytes,5,opt,name=group"`
}
// FlexVolume represents a generic volume resource that is
// provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.
// provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.
type FlexVolumeSource struct {
// Driver is the name of the driver to use for this volume.
Driver string `json:"driver" protobuf:"bytes,1,opt,name=driver"`
@ -770,8 +805,18 @@ type SecretVolumeSource struct {
// the volume setup will error. Paths must be relative and may not contain
// the '..' path or start with '..'.
Items []KeyToPath `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"`
// Optional: mode bits to use on created files by default. Must be a
// value between 0 and 0777. Defaults to 0644.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
DefaultMode *int32 `json:"defaultMode,omitempty" protobuf:"bytes,3,opt,name=defaultMode"`
}
const (
SecretVolumeSourceDefaultMode int32 = 0644
)
// Represents an NFS mount that lasts the lifetime of a pod.
// NFS volumes do not support ownership management or SELinux relabeling.
type NFSVolumeSource struct {
@ -818,7 +863,7 @@ type ISCSIVolumeSource struct {
// 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 world wide names (WWNs)
// Required: FC target worldwide names (WWNs)
TargetWWNs []string `json:"targetWWNs" protobuf:"bytes,1,rep,name=targetWWNs"`
// Required: FC target lun number
Lun *int32 `json:"lun" protobuf:"varint,2,opt,name=lun"`
@ -852,6 +897,30 @@ type VsphereVirtualDiskVolumeSource struct {
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
FSType string `json:"fsType,omitempty" protobuf:"bytes,2,opt,name=fsType"`
}
type AzureDataDiskCachingMode string
const (
AzureDataDiskCachingNone AzureDataDiskCachingMode = "None"
AzureDataDiskCachingReadOnly AzureDataDiskCachingMode = "ReadOnly"
AzureDataDiskCachingReadWrite AzureDataDiskCachingMode = "ReadWrite"
)
// AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
type AzureDiskVolumeSource struct {
// The Name of the data disk in the blob storage
DiskName string `json:"diskName" protobuf:"bytes,1,opt,name=diskName"`
// The URI the data disk in the blob storage
DataDiskURI string `json:"diskURI" protobuf:"bytes,2,opt,name=diskURI"`
// Host Caching mode: None, Read Only, Read Write.
CachingMode *AzureDataDiskCachingMode `json:"cachingMode,omitempty" protobuf:"bytes,3,opt,name=cachingMode,casttype=AzureDataDiskCachingMode"`
// Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
FSType *string `json:"fsType,omitempty" protobuf:"bytes,4,opt,name=fsType"`
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
ReadOnly *bool `json:"readOnly,omitempty" protobuf:"varint,5,opt,name=readOnly"`
}
// Adapts a ConfigMap into a volume.
//
@ -869,8 +938,18 @@ type ConfigMapVolumeSource struct {
// the volume setup will error. Paths must be relative and may not contain
// the '..' path or start with '..'.
Items []KeyToPath `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"`
// Optional: mode bits to use on created files by default. Must be a
// value between 0 and 0777. Defaults to 0644.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
DefaultMode *int32 `json:"defaultMode,omitempty" protobuf:"varint,3,opt,name=defaultMode"`
}
const (
ConfigMapVolumeSourceDefaultMode int32 = 0644
)
// Maps a string key to a path within a volume.
type KeyToPath struct {
// The key to project.
@ -881,6 +960,11 @@ type KeyToPath struct {
// May not contain the path element '..'.
// May not start with the string '..'.
Path string `json:"path" protobuf:"bytes,2,opt,name=path"`
// Optional: mode bits to use on this file, must be a value between 0
// and 0777. If not specified, the volume defaultMode will be used.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
Mode *int32 `json:"mode,omitempty" protobuf:"varint,3,opt,name=mode"`
}
// ContainerPort represents a network port in a single container.
@ -941,7 +1025,8 @@ type EnvVar struct {
// EnvVarSource represents a source for the value of an EnvVar.
type EnvVarSource struct {
// Selects a field of the pod; only name and namespace are supported.
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
// spec.nodeName, spec.serviceAccountName, status.podIP.
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
@ -1089,12 +1174,12 @@ type Capabilities struct {
// ResourceRequirements describes the compute resource requirements.
type ResourceRequirements struct {
// Limits describes the maximum amount of compute resources allowed.
// More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications
// More info: http://kubernetes.io/docs/user-guide/compute-resources/
Limits ResourceList `json:"limits,omitempty" protobuf:"bytes,1,rep,name=limits,casttype=ResourceList,castkey=ResourceName"`
// Requests describes the minimum amount of compute resources required.
// If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
// otherwise to an implementation-defined value.
// More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications
// More info: http://kubernetes.io/docs/user-guide/compute-resources/
Requests ResourceList `json:"requests,omitempty" protobuf:"bytes,2,rep,name=requests,casttype=ResourceList,castkey=ResourceName"`
}
@ -1655,11 +1740,17 @@ const (
const (
// This annotation key will be used to contain an array of v1 JSON encoded Containers
// for init containers. The annotation will be placed into the internal type and cleared.
// This key is only recognized by version >= 1.4.
PodInitContainersBetaAnnotationKey = "pod.beta.kubernetes.io/init-containers"
// This annotation key will be used to contain an array of v1 JSON encoded Containers
// for init containers. The annotation will be placed into the internal type and cleared.
// This key is recognized by version >= 1.3. For version 1.4 code, this key
// will have its value copied to the beta key.
PodInitContainersAnnotationKey = "pod.alpha.kubernetes.io/init-containers"
// This annotation key will be used to contain an array of v1 JSON encoded
// ContainerStatuses for init containers. The annotation will be placed into the internal
// type and cleared.
PodInitContainerStatusesAnnotationKey = "pod.alpha.kubernetes.io/init-container-statuses"
PodInitContainerStatusesAnnotationKey = "pod.beta.kubernetes.io/init-container-statuses"
)
// PodSpec is a description of a pod.
@ -1951,6 +2042,9 @@ type ReplicationControllerStatus struct {
// The number of pods that have labels matching the labels of the pod template of the replication controller.
FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty" protobuf:"varint,2,opt,name=fullyLabeledReplicas"`
// The number of ready replicas for this replication controller.
ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,4,opt,name=readyReplicas"`
// ObservedGeneration reflects the generation of the most recently observed replication controller.
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"`
}
@ -2017,6 +2111,11 @@ const (
// external load balancer (if the cloud provider supports it), in addition
// to 'NodePort' type.
ServiceTypeLoadBalancer ServiceType = "LoadBalancer"
// ServiceTypeExternalName means a service consists of only a reference to
// an external name that kubedns or equivalent will return as a CNAME
// record, with no exposing or proxying of any pods involved.
ServiceTypeExternalName ServiceType = "ExternalName"
)
// ServiceStatus represents the current status of a service.
@ -2051,24 +2150,39 @@ type ServiceSpec struct {
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
Ports []ServicePort `json:"ports" patchStrategy:"merge" patchMergeKey:"port" protobuf:"bytes,1,rep,name=ports"`
// This service will route traffic to pods having labels matching this selector.
// Label keys and values that must match in order to receive traffic for this service.
// If not specified, endpoints must be manually specified and the system will not automatically manage them.
// Route service traffic to pods with label keys and values matching this
// selector. If empty or not present, the service is assumed to have an
// external process managing its endpoints, which Kubernetes will not
// modify. Only applies to types ClusterIP, NodePort, and LoadBalancer.
// Ignored if type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"`
// ClusterIP is usually assigned by the master and is the IP address of the service.
// If specified, it will be allocated to the service if it is unused
// or else creation of the service will fail.
// Valid values are None, empty string (""), or a valid IP address.
// 'None' can be specified for a headless service when proxying is not required.
// Cannot be updated.
// clusterIP is the IP address of the service and is usually assigned
// randomly by the master. If an address is specified manually and is not in
// use by others, it will be allocated to the service; otherwise, creation
// of the service will fail. This field can not be changed through updates.
// Valid values are "None", empty string (""), or a valid IP address. "None"
// can be specified for headless services when proxying is not required.
// Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
// type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
ClusterIP string `json:"clusterIP,omitempty" protobuf:"bytes,3,opt,name=clusterIP"`
// Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer.
// Defaults to ClusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services
// type determines how the Service is exposed. Defaults to ClusterIP. Valid
// options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to
// endpoints. Endpoints are determined by the selector or if that is not
// specified, by manual construction of an Endpoints object. If clusterIP is
// "None", no virtual IP is allocated and the endpoints are published as a
// set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which
// routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an
// external load-balancer (if supported in the current cloud) which routes
// to the clusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Type ServiceType `json:"type,omitempty" protobuf:"bytes,4,opt,name=type,casttype=ServiceType"`
// externalIPs is a list of IP addresses for which nodes in the cluster
@ -2107,6 +2221,11 @@ type ServiceSpec struct {
// cloud-provider does not support the feature."
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md
LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty" protobuf:"bytes,9,opt,name=loadBalancerSourceRanges"`
// externalName is the external reference that kubedns or equivalent will
// return as a CNAME record for this service. No proxying will be involved.
// Must be a valid DNS name and requires Type to be ExternalName.
ExternalName string `json:"externalName,omitempty" protobuf:"bytes,10,opt,name=externalName"`
}
// ServicePort contains information on service's port.
@ -2279,6 +2398,8 @@ type EndpointAddress struct {
IP string `json:"ip" protobuf:"bytes,1,opt,name=ip"`
// The Hostname of this endpoint
Hostname string `json:"hostname,omitempty" protobuf:"bytes,3,opt,name=hostname"`
// Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.
NodeName *string `json:"nodeName,omitempty" protobuf:"bytes,4,opt,name=nodeName"`
// Reference to object providing the endpoint.
TargetRef *ObjectReference `json:"targetRef,omitempty" protobuf:"bytes,2,opt,name=targetRef"`
}
@ -2376,6 +2497,7 @@ type NodeStatus struct {
Allocatable ResourceList `json:"allocatable,omitempty" protobuf:"bytes,2,rep,name=allocatable,casttype=ResourceList,castkey=ResourceName"`
// NodePhase is the recently observed lifecycle phase of the node.
// More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase
// The field is never populated, and now is deprecated.
Phase NodePhase `json:"phase,omitempty" protobuf:"bytes,3,opt,name=phase,casttype=NodePhase"`
// Conditions is an array of current observed node conditions.
// More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-condition
@ -2476,7 +2598,7 @@ const (
NodeNetworkUnavailable NodeConditionType = "NetworkUnavailable"
)
// NodeCondition contains condition infromation for a node.
// NodeCondition contains condition information for a node.
type NodeCondition struct {
// Type of node condition.
Type NodeConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=NodeConditionType"`
@ -3284,8 +3406,18 @@ type ComponentStatusList struct {
type DownwardAPIVolumeSource struct {
// Items is a list of downward API volume file
Items []DownwardAPIVolumeFile `json:"items,omitempty" protobuf:"bytes,1,rep,name=items"`
// Optional: mode bits to use on created files by default. Must be a
// value between 0 and 0777. Defaults to 0644.
// Directories within the path are not affected by this setting.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
DefaultMode *int32 `json:"defaultMode,omitempty" protobuf:"varint,2,opt,name=defaultMode"`
}
const (
DownwardAPIVolumeSourceDefaultMode int32 = 0644
)
// DownwardAPIVolumeFile represents information to create the file containing the pod field
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 '..'
@ -3295,6 +3427,11 @@ type DownwardAPIVolumeFile struct {
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" protobuf:"bytes,3,opt,name=resourceFieldRef"`
// Optional: mode bits to use on this file, must be a value between 0
// and 0777. If not specified, the volume defaultMode will be used.
// This might be in conflict with other options that affect the file
// mode, like fsGroup, and the result can be other mode bits set.
Mode *int32 `json:"mode,omitempty" protobuf:"varint,4,opt,name=mode"`
}
// SecurityContext holds security configuration that will be applied to a container.

View file

@ -69,6 +69,19 @@ func (AvoidPods) SwaggerDoc() map[string]string {
return map_AvoidPods
}
var map_AzureDiskVolumeSource = map[string]string{
"": "AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.",
"diskName": "The Name of the data disk in the blob storage",
"diskURI": "The URI the data disk in the blob storage",
"cachingMode": "Host Caching mode: None, Read Only, Read Write.",
"fsType": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.",
"readOnly": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.",
}
func (AzureDiskVolumeSource) SwaggerDoc() map[string]string {
return map_AzureDiskVolumeSource
}
var map_AzureFileVolumeSource = map[string]string{
"": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"secretName": "the name of secret that contains Azure Storage Account Name and Key",
@ -187,8 +200,9 @@ func (ConfigMapList) SwaggerDoc() map[string]string {
}
var map_ConfigMapVolumeSource = map[string]string{
"": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.",
"items": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
"": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.",
"items": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
"defaultMode": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
}
func (ConfigMapVolumeSource) SwaggerDoc() map[string]string {
@ -330,6 +344,7 @@ var map_DownwardAPIVolumeFile = map[string]string{
"path": "Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'",
"fieldRef": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.",
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.",
"mode": "Optional: mode bits to use on this file, must be a value between 0 and 0777. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
}
func (DownwardAPIVolumeFile) SwaggerDoc() map[string]string {
@ -337,8 +352,9 @@ func (DownwardAPIVolumeFile) SwaggerDoc() map[string]string {
}
var map_DownwardAPIVolumeSource = map[string]string{
"": "DownwardAPIVolumeSource represents a volume containing downward API info. Downward API volumes support ownership management and SELinux relabeling.",
"items": "Items is a list of downward API volume file",
"": "DownwardAPIVolumeSource represents a volume containing downward API info. Downward API volumes support ownership management and SELinux relabeling.",
"items": "Items is a list of downward API volume file",
"defaultMode": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
}
func (DownwardAPIVolumeSource) SwaggerDoc() map[string]string {
@ -358,6 +374,7 @@ var map_EndpointAddress = map[string]string{
"": "EndpointAddress is a tuple that describes single IP address.",
"ip": "The IP of this endpoint. May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast ((224.0.0.0/24). IPv6 is also accepted but not fully supported on all platforms. Also, certain kubernetes components, like kube-proxy, are not IPv6 ready.",
"hostname": "The Hostname of this endpoint",
"nodeName": "Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.",
"targetRef": "Reference to object providing the endpoint.",
}
@ -420,7 +437,7 @@ func (EnvVar) SwaggerDoc() map[string]string {
var map_EnvVarSource = map[string]string{
"": "EnvVarSource represents a source for the value of an EnvVar.",
"fieldRef": "Selects a field of the pod; only name and namespace are supported.",
"fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.",
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.",
"configMapKeyRef": "Selects a key of a ConfigMap.",
"secretKeyRef": "Selects a key of a secret in the pod's namespace",
@ -488,7 +505,7 @@ func (ExportOptions) SwaggerDoc() map[string]string {
var map_FCVolumeSource = map[string]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.",
"targetWWNs": "Required: FC target world wide names (WWNs)",
"targetWWNs": "Required: FC target worldwide names (WWNs)",
"lun": "Required: FC target lun number",
"fsType": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.",
"readOnly": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.",
@ -499,7 +516,7 @@ func (FCVolumeSource) SwaggerDoc() map[string]string {
}
var map_FlexVolumeSource = map[string]string{
"": "FlexVolume represents a generic volume resource that is provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.",
"": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.",
"driver": "Driver is the name of the driver to use for this volume.",
"fsType": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". The default filesystem depends on FlexVolume script.",
"secretRef": "Optional: SecretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.",
@ -615,6 +632,7 @@ var map_KeyToPath = map[string]string{
"": "Maps a string key to a path within a volume.",
"key": "The key to project.",
"path": "The relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'.",
"mode": "Optional: mode bits to use on this file, must be a value between 0 and 0777. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
}
func (KeyToPath) SwaggerDoc() map[string]string {
@ -807,7 +825,7 @@ func (NodeAffinity) SwaggerDoc() map[string]string {
}
var map_NodeCondition = map[string]string{
"": "NodeCondition contains condition infromation for a node.",
"": "NodeCondition contains condition information for a node.",
"type": "Type of node condition.",
"status": "Status of the condition, one of True, False, Unknown.",
"lastHeartbeatTime": "Last time we got an update on a given condition.",
@ -893,7 +911,7 @@ var map_NodeStatus = map[string]string{
"": "NodeStatus is information about the current status of a node.",
"capacity": "Capacity represents the total resources of a node. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity for more details.",
"allocatable": "Allocatable represents the resources of a node that are available for scheduling. Defaults to Capacity.",
"phase": "NodePhase is the recently observed lifecycle phase of the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase",
"phase": "NodePhase is the recently observed lifecycle phase of the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase The field is never populated, and now is deprecated.",
"conditions": "Conditions is an array of current observed node conditions. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-condition",
"addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses",
"daemonEndpoints": "Endpoints of daemons running on the Node.",
@ -951,6 +969,7 @@ var map_ObjectMeta = map[string]string{
"annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://releases.k8s.io/HEAD/docs/user-guide/annotations.md",
"ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.",
"finalizers": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed.",
"clusterName": "The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.",
}
func (ObjectMeta) SwaggerDoc() map[string]string {
@ -1073,9 +1092,11 @@ var map_PersistentVolumeSource = map[string]string{
"cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime",
"fc": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.",
"flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running",
"flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.",
"flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.",
"azureFile": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"vsphereVolume": "VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine",
"quobyte": "Quobyte represents a Quobyte mount on the host that shares a pod's lifetime",
"azureDisk": "AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.",
}
func (PersistentVolumeSource) SwaggerDoc() map[string]string {
@ -1087,7 +1108,7 @@ var map_PersistentVolumeSpec = map[string]string{
"capacity": "A description of the persistent volume's resources and capacity. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity",
"accessModes": "AccessModes contains all ways the volume can be mounted. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes",
"claimRef": "ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. Expected to be non-nil when bound. claim.VolumeName is the authoritative bind between PV and PVC. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#binding",
"persistentVolumeReclaimPolicy": "What happens to a persistent volume when released from its claim. Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#recycling-policy",
"persistentVolumeReclaimPolicy": "What happens to a persistent volume when released from its claim. Valid options are Retain (default) and Recycle. Recycling must be supported by the volume plugin underlying this persistent volume. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#recycling-policy",
}
func (PersistentVolumeSpec) SwaggerDoc() map[string]string {
@ -1370,6 +1391,19 @@ func (Probe) SwaggerDoc() map[string]string {
return map_Probe
}
var map_QuobyteVolumeSource = map[string]string{
"": "Represents a Quobyte mount that lasts the lifetime of a pod. Quobyte volumes do not support ownership management or SELinux relabeling.",
"registry": "Registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes",
"volume": "Volume is a string that references an already created Quobyte volume by name.",
"readOnly": "ReadOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false.",
"user": "User to map volume access to Defaults to serivceaccount user",
"group": "Group to map volume access to Default is no group",
}
func (QuobyteVolumeSource) SwaggerDoc() map[string]string {
return map_QuobyteVolumeSource
}
var map_RBDVolumeSource = map[string]string{
"": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
"monitors": "A collection of Ceph monitors. More info: http://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
@ -1433,6 +1467,7 @@ var map_ReplicationControllerStatus = map[string]string{
"": "ReplicationControllerStatus represents the current status of a replication controller.",
"replicas": "Replicas is the most recently oberved number of replicas. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller",
"fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replication controller.",
"readyReplicas": "The number of ready replicas for this replication controller.",
"observedGeneration": "ObservedGeneration reflects the generation of the most recently observed replication controller.",
}
@ -1494,8 +1529,8 @@ func (ResourceQuotaStatus) SwaggerDoc() map[string]string {
var map_ResourceRequirements = map[string]string{
"": "ResourceRequirements describes the compute resource requirements.",
"limits": "Limits describes the maximum amount of compute resources allowed. More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications",
"requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications",
"limits": "Limits describes the maximum amount of compute resources allowed. More info: http://kubernetes.io/docs/user-guide/compute-resources/",
"requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: http://kubernetes.io/docs/user-guide/compute-resources/",
}
func (ResourceRequirements) SwaggerDoc() map[string]string {
@ -1546,9 +1581,10 @@ func (SecretList) SwaggerDoc() map[string]string {
}
var map_SecretVolumeSource = map[string]string{
"": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.",
"secretName": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets",
"items": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
"": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.",
"secretName": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets",
"items": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
"defaultMode": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
}
func (SecretVolumeSource) SwaggerDoc() map[string]string {
@ -1645,14 +1681,15 @@ func (ServiceProxyOptions) SwaggerDoc() map[string]string {
var map_ServiceSpec = map[string]string{
"": "ServiceSpec describes the attributes that a user creates on a service.",
"ports": "The list of ports that are exposed by this service. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"selector": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If not specified, endpoints must be manually specified and the system will not automatically manage them. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview",
"clusterIP": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"type": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services",
"selector": "Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview",
"clusterIP": "clusterIP is the IP address of the service and is usually assigned randomly by the master. If an address is specified manually and is not in use by others, it will be allocated to the service; otherwise, creation of the service will fail. This field can not be changed through updates. Valid values are \"None\", empty string (\"\"), or a valid IP address. \"None\" can be specified for headless services when proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"type": "type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. \"ExternalName\" maps to the specified externalName. \"ClusterIP\" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is \"None\", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP. \"NodePort\" builds on ClusterIP and allocates a port on every node which routes to the clusterIP. \"LoadBalancer\" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview",
"externalIPs": "externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system. A previous form of this functionality exists as the deprecatedPublicIPs field. When using this field, callers should also clear the deprecatedPublicIPs field.",
"deprecatedPublicIPs": "deprecatedPublicIPs is deprecated and replaced by the externalIPs field with almost the exact same semantics. This field is retained in the v1 API for compatibility until at least 8/20/2016. It will be removed from any new API revisions. If both deprecatedPublicIPs *and* externalIPs are set, deprecatedPublicIPs is used.",
"sessionAffinity": "Supports \"ClientIP\" and \"None\". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"loadBalancerIP": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.",
"loadBalancerSourceRanges": "If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature.\" More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md",
"externalName": "externalName is the external reference that kubedns or equivalent will return as a CNAME record for this service. No proxying will be involved. Must be a valid DNS name and requires Type to be ExternalName.",
}
func (ServiceSpec) SwaggerDoc() map[string]string {
@ -1734,7 +1771,7 @@ var map_VolumeSource = map[string]string{
"glusterfs": "Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/volumes/glusterfs/README.md",
"persistentVolumeClaim": "PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims",
"rbd": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/volumes/rbd/README.md",
"flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.",
"flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. This is an alpha feature and may change in future.",
"cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md",
"cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime",
"flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running",
@ -1743,6 +1780,8 @@ var map_VolumeSource = map[string]string{
"azureFile": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"configMap": "ConfigMap represents a configMap that should populate this volume",
"vsphereVolume": "VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine",
"quobyte": "Quobyte represents a Quobyte mount on the host that shares a pod's lifetime",
"azureDisk": "AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.",
}
func (VolumeSource) SwaggerDoc() map[string]string {

View file

@ -44,6 +44,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_api_AttachedVolume_To_v1_AttachedVolume,
Convert_v1_AvoidPods_To_api_AvoidPods,
Convert_api_AvoidPods_To_v1_AvoidPods,
Convert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource,
Convert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource,
Convert_v1_AzureFileVolumeSource_To_api_AzureFileVolumeSource,
Convert_api_AzureFileVolumeSource_To_v1_AzureFileVolumeSource,
Convert_v1_Binding_To_api_Binding,
@ -270,6 +272,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_api_PreferredSchedulingTerm_To_v1_PreferredSchedulingTerm,
Convert_v1_Probe_To_api_Probe,
Convert_api_Probe_To_v1_Probe,
Convert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource,
Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource,
Convert_v1_RBDVolumeSource_To_api_RBDVolumeSource,
Convert_api_RBDVolumeSource_To_v1_RBDVolumeSource,
Convert_v1_RangeAllocation_To_api_RangeAllocation,
@ -495,6 +499,45 @@ func Convert_api_AvoidPods_To_v1_AvoidPods(in *api.AvoidPods, out *AvoidPods, s
return autoConvert_api_AvoidPods_To_v1_AvoidPods(in, out, s)
}
func autoConvert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource(in *AzureDiskVolumeSource, out *api.AzureDiskVolumeSource, s conversion.Scope) error {
SetDefaults_AzureDiskVolumeSource(in)
out.DiskName = in.DiskName
out.DataDiskURI = in.DataDiskURI
if in.CachingMode != nil {
in, out := &in.CachingMode, &out.CachingMode
*out = new(api.AzureDataDiskCachingMode)
**out = api.AzureDataDiskCachingMode(**in)
} else {
out.CachingMode = nil
}
out.FSType = in.FSType
out.ReadOnly = in.ReadOnly
return nil
}
func Convert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource(in *AzureDiskVolumeSource, out *api.AzureDiskVolumeSource, s conversion.Scope) error {
return autoConvert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource(in, out, s)
}
func autoConvert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(in *api.AzureDiskVolumeSource, out *AzureDiskVolumeSource, s conversion.Scope) error {
out.DiskName = in.DiskName
out.DataDiskURI = in.DataDiskURI
if in.CachingMode != nil {
in, out := &in.CachingMode, &out.CachingMode
*out = new(AzureDataDiskCachingMode)
**out = AzureDataDiskCachingMode(**in)
} else {
out.CachingMode = nil
}
out.FSType = in.FSType
out.ReadOnly = in.ReadOnly
return nil
}
func Convert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(in *api.AzureDiskVolumeSource, out *AzureDiskVolumeSource, s conversion.Scope) error {
return autoConvert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(in, out, s)
}
func autoConvert_v1_AzureFileVolumeSource_To_api_AzureFileVolumeSource(in *AzureFileVolumeSource, out *api.AzureFileVolumeSource, s conversion.Scope) error {
out.SecretName = in.SecretName
out.ShareName = in.ShareName
@ -899,6 +942,7 @@ func Convert_api_ConfigMapList_To_v1_ConfigMapList(in *api.ConfigMapList, out *C
}
func autoConvert_v1_ConfigMapVolumeSource_To_api_ConfigMapVolumeSource(in *ConfigMapVolumeSource, out *api.ConfigMapVolumeSource, s conversion.Scope) error {
SetDefaults_ConfigMapVolumeSource(in)
if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
return err
}
@ -913,6 +957,7 @@ func autoConvert_v1_ConfigMapVolumeSource_To_api_ConfigMapVolumeSource(in *Confi
} else {
out.Items = nil
}
out.DefaultMode = in.DefaultMode
return nil
}
@ -935,6 +980,7 @@ func autoConvert_api_ConfigMapVolumeSource_To_v1_ConfigMapVolumeSource(in *api.C
} else {
out.Items = nil
}
out.DefaultMode = in.DefaultMode
return nil
}
@ -1442,6 +1488,7 @@ func autoConvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *Downw
} else {
out.ResourceFieldRef = nil
}
out.Mode = in.Mode
return nil
}
@ -1469,6 +1516,7 @@ func autoConvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.D
} else {
out.ResourceFieldRef = nil
}
out.Mode = in.Mode
return nil
}
@ -1477,6 +1525,7 @@ func Convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.Downw
}
func autoConvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error {
SetDefaults_DownwardAPIVolumeSource(in)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]api.DownwardAPIVolumeFile, len(*in))
@ -1488,6 +1537,7 @@ func autoConvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *D
} else {
out.Items = nil
}
out.DefaultMode = in.DefaultMode
return nil
}
@ -1507,6 +1557,7 @@ func autoConvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *a
} else {
out.Items = nil
}
out.DefaultMode = in.DefaultMode
return nil
}
@ -1535,6 +1586,7 @@ func Convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDi
func autoConvert_v1_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out *api.EndpointAddress, s conversion.Scope) error {
out.IP = in.IP
out.Hostname = in.Hostname
out.NodeName = in.NodeName
if in.TargetRef != nil {
in, out := &in.TargetRef, &out.TargetRef
*out = new(api.ObjectReference)
@ -1554,6 +1606,7 @@ func Convert_v1_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out
func autoConvert_api_EndpointAddress_To_v1_EndpointAddress(in *api.EndpointAddress, out *EndpointAddress, s conversion.Scope) error {
out.IP = in.IP
out.Hostname = in.Hostname
out.NodeName = in.NodeName
if in.TargetRef != nil {
in, out := &in.TargetRef, &out.TargetRef
*out = new(ObjectReference)
@ -2418,6 +2471,7 @@ func Convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSo
func autoConvert_v1_KeyToPath_To_api_KeyToPath(in *KeyToPath, out *api.KeyToPath, s conversion.Scope) error {
out.Key = in.Key
out.Path = in.Path
out.Mode = in.Mode
return nil
}
@ -2428,6 +2482,7 @@ func Convert_v1_KeyToPath_To_api_KeyToPath(in *KeyToPath, out *api.KeyToPath, s
func autoConvert_api_KeyToPath_To_v1_KeyToPath(in *api.KeyToPath, out *KeyToPath, s conversion.Scope) error {
out.Key = in.Key
out.Path = in.Path
out.Mode = in.Mode
return nil
}
@ -3663,6 +3718,7 @@ func autoConvert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.Object
out.OwnerReferences = nil
}
out.Finalizers = in.Finalizers
out.ClusterName = in.ClusterName
return nil
}
@ -3697,6 +3753,7 @@ func autoConvert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *Object
out.OwnerReferences = nil
}
out.Finalizers = in.Finalizers
out.ClusterName = in.ClusterName
return nil
}
@ -4185,6 +4242,24 @@ func autoConvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *Per
} else {
out.VsphereVolume = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(api.QuobyteVolumeSource)
if err := Convert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.Quobyte = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(api.AzureDiskVolumeSource)
if err := Convert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
@ -4247,6 +4322,15 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api
} else {
out.RBD = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(QuobyteVolumeSource)
if err := Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.Quobyte = nil
}
if in.ISCSI != nil {
in, out := &in.ISCSI, &out.ISCSI
*out = new(ISCSIVolumeSource)
@ -4319,6 +4403,15 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api
} else {
out.VsphereVolume = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(AzureDiskVolumeSource)
if err := Convert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
@ -5347,6 +5440,32 @@ func Convert_api_Probe_To_v1_Probe(in *api.Probe, out *Probe, s conversion.Scope
return autoConvert_api_Probe_To_v1_Probe(in, out, s)
}
func autoConvert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource(in *QuobyteVolumeSource, out *api.QuobyteVolumeSource, s conversion.Scope) error {
out.Registry = in.Registry
out.Volume = in.Volume
out.ReadOnly = in.ReadOnly
out.User = in.User
out.Group = in.Group
return nil
}
func Convert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource(in *QuobyteVolumeSource, out *api.QuobyteVolumeSource, s conversion.Scope) error {
return autoConvert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource(in, out, s)
}
func autoConvert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *api.QuobyteVolumeSource, out *QuobyteVolumeSource, s conversion.Scope) error {
out.Registry = in.Registry
out.Volume = in.Volume
out.ReadOnly = in.ReadOnly
out.User = in.User
out.Group = in.Group
return nil
}
func Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *api.QuobyteVolumeSource, out *QuobyteVolumeSource, s conversion.Scope) error {
return autoConvert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in, out, s)
}
func autoConvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error {
SetDefaults_RBDVolumeSource(in)
out.CephMonitors = in.CephMonitors
@ -5560,6 +5679,7 @@ func autoConvert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(i
func autoConvert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in *ReplicationControllerStatus, out *api.ReplicationControllerStatus, s conversion.Scope) error {
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
out.ObservedGeneration = in.ObservedGeneration
return nil
}
@ -5571,6 +5691,7 @@ func Convert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(i
func autoConvert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(in *api.ReplicationControllerStatus, out *ReplicationControllerStatus, s conversion.Scope) error {
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
out.ObservedGeneration = in.ObservedGeneration
return nil
}
@ -5969,6 +6090,7 @@ func Convert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList
}
func autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error {
SetDefaults_SecretVolumeSource(in)
out.SecretName = in.SecretName
if in.Items != nil {
in, out := &in.Items, &out.Items
@ -5981,6 +6103,7 @@ func autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolum
} else {
out.Items = nil
}
out.DefaultMode = in.DefaultMode
return nil
}
@ -6001,6 +6124,7 @@ func autoConvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretV
} else {
out.Items = nil
}
out.DefaultMode = in.DefaultMode
return nil
}
@ -6382,6 +6506,7 @@ func autoConvert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.Ser
out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity)
out.LoadBalancerIP = in.LoadBalancerIP
out.LoadBalancerSourceRanges = in.LoadBalancerSourceRanges
out.ExternalName = in.ExternalName
return nil
}
@ -6400,6 +6525,7 @@ func autoConvert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *Ser
}
out.Selector = in.Selector
out.ClusterIP = in.ClusterIP
out.ExternalName = in.ExternalName
out.ExternalIPs = in.ExternalIPs
out.LoadBalancerIP = in.LoadBalancerIP
out.SessionAffinity = ServiceAffinity(in.SessionAffinity)
@ -6727,6 +6853,24 @@ func autoConvert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.
} else {
out.VsphereVolume = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(api.QuobyteVolumeSource)
if err := Convert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.Quobyte = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(api.AzureDiskVolumeSource)
if err := Convert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
@ -6834,6 +6978,15 @@ func autoConvert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *
} else {
out.RBD = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(QuobyteVolumeSource)
if err := Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.Quobyte = nil
}
if in.FlexVolume != nil {
in, out := &in.FlexVolume, &out.FlexVolume
*out = new(FlexVolumeSource)
@ -6915,6 +7068,15 @@ func autoConvert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *
} else {
out.VsphereVolume = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(AzureDiskVolumeSource)
if err := Convert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(*in, *out, s); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}

View file

@ -40,6 +40,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Affinity, InType: reflect.TypeOf(&Affinity{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_AttachedVolume, InType: reflect.TypeOf(&AttachedVolume{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_AvoidPods, InType: reflect.TypeOf(&AvoidPods{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_AzureDiskVolumeSource, InType: reflect.TypeOf(&AzureDiskVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_AzureFileVolumeSource, InType: reflect.TypeOf(&AzureFileVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Binding, InType: reflect.TypeOf(&Binding{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Capabilities, InType: reflect.TypeOf(&Capabilities{})},
@ -153,6 +154,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PreferAvoidPodsEntry, InType: reflect.TypeOf(&PreferAvoidPodsEntry{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PreferredSchedulingTerm, InType: reflect.TypeOf(&PreferredSchedulingTerm{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Probe, InType: reflect.TypeOf(&Probe{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_QuobyteVolumeSource, InType: reflect.TypeOf(&QuobyteVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_RBDVolumeSource, InType: reflect.TypeOf(&RBDVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_RangeAllocation, InType: reflect.TypeOf(&RangeAllocation{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_ReplicationController, InType: reflect.TypeOf(&ReplicationController{})},
@ -267,6 +269,37 @@ func DeepCopy_v1_AvoidPods(in interface{}, out interface{}, c *conversion.Cloner
}
}
func DeepCopy_v1_AzureDiskVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*AzureDiskVolumeSource)
out := out.(*AzureDiskVolumeSource)
out.DiskName = in.DiskName
out.DataDiskURI = in.DataDiskURI
if in.CachingMode != nil {
in, out := &in.CachingMode, &out.CachingMode
*out = new(AzureDataDiskCachingMode)
**out = **in
} else {
out.CachingMode = nil
}
if in.FSType != nil {
in, out := &in.FSType, &out.FSType
*out = new(string)
**out = **in
} else {
out.FSType = nil
}
if in.ReadOnly != nil {
in, out := &in.ReadOnly, &out.ReadOnly
*out = new(bool)
**out = **in
} else {
out.ReadOnly = nil
}
return nil
}
}
func DeepCopy_v1_AzureFileVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*AzureFileVolumeSource)
@ -469,11 +502,20 @@ func DeepCopy_v1_ConfigMapVolumeSource(in interface{}, out interface{}, c *conve
in, out := &in.Items, &out.Items
*out = make([]KeyToPath, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
if err := DeepCopy_v1_KeyToPath(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
if in.DefaultMode != nil {
in, out := &in.DefaultMode, &out.DefaultMode
*out = new(int32)
**out = **in
} else {
out.DefaultMode = nil
}
return nil
}
}
@ -754,6 +796,13 @@ func DeepCopy_v1_DownwardAPIVolumeFile(in interface{}, out interface{}, c *conve
} else {
out.ResourceFieldRef = nil
}
if in.Mode != nil {
in, out := &in.Mode, &out.Mode
*out = new(int32)
**out = **in
} else {
out.Mode = nil
}
return nil
}
}
@ -773,6 +822,13 @@ func DeepCopy_v1_DownwardAPIVolumeSource(in interface{}, out interface{}, c *con
} else {
out.Items = nil
}
if in.DefaultMode != nil {
in, out := &in.DefaultMode, &out.DefaultMode
*out = new(int32)
**out = **in
} else {
out.DefaultMode = nil
}
return nil
}
}
@ -792,6 +848,13 @@ func DeepCopy_v1_EndpointAddress(in interface{}, out interface{}, c *conversion.
out := out.(*EndpointAddress)
out.IP = in.IP
out.Hostname = in.Hostname
if in.NodeName != nil {
in, out := &in.NodeName, &out.NodeName
*out = new(string)
**out = **in
} else {
out.NodeName = nil
}
if in.TargetRef != nil {
in, out := &in.TargetRef, &out.TargetRef
*out = new(ObjectReference)
@ -1218,6 +1281,13 @@ func DeepCopy_v1_KeyToPath(in interface{}, out interface{}, c *conversion.Cloner
out := out.(*KeyToPath)
out.Key = in.Key
out.Path = in.Path
if in.Mode != nil {
in, out := &in.Mode, &out.Mode
*out = new(int32)
**out = **in
} else {
out.Mode = nil
}
return nil
}
}
@ -1851,6 +1921,7 @@ func DeepCopy_v1_ObjectMeta(in interface{}, out interface{}, c *conversion.Clone
} else {
out.Finalizers = nil
}
out.ClusterName = in.ClusterName
return nil
}
}
@ -2142,6 +2213,22 @@ func DeepCopy_v1_PersistentVolumeSource(in interface{}, out interface{}, c *conv
} else {
out.VsphereVolume = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(QuobyteVolumeSource)
**out = **in
} else {
out.Quobyte = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(AzureDiskVolumeSource)
if err := DeepCopy_v1_AzureDiskVolumeSource(*in, *out, c); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
}
@ -2745,6 +2832,19 @@ func DeepCopy_v1_Probe(in interface{}, out interface{}, c *conversion.Cloner) er
}
}
func DeepCopy_v1_QuobyteVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*QuobyteVolumeSource)
out := out.(*QuobyteVolumeSource)
out.Registry = in.Registry
out.Volume = in.Volume
out.ReadOnly = in.ReadOnly
out.User = in.User
out.Group = in.Group
return nil
}
}
func DeepCopy_v1_RBDVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RBDVolumeSource)
@ -2869,6 +2969,7 @@ func DeepCopy_v1_ReplicationControllerStatus(in interface{}, out interface{}, c
out := out.(*ReplicationControllerStatus)
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
out.ObservedGeneration = in.ObservedGeneration
return nil
}
@ -3089,11 +3190,20 @@ func DeepCopy_v1_SecretVolumeSource(in interface{}, out interface{}, c *conversi
in, out := &in.Items, &out.Items
*out = make([]KeyToPath, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
if err := DeepCopy_v1_KeyToPath(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
if in.DefaultMode != nil {
in, out := &in.DefaultMode, &out.DefaultMode
*out = new(int32)
**out = **in
} else {
out.DefaultMode = nil
}
return nil
}
}
@ -3320,6 +3430,7 @@ func DeepCopy_v1_ServiceSpec(in interface{}, out interface{}, c *conversion.Clon
} else {
out.LoadBalancerSourceRanges = nil
}
out.ExternalName = in.ExternalName
return nil
}
}
@ -3549,6 +3660,22 @@ func DeepCopy_v1_VolumeSource(in interface{}, out interface{}, c *conversion.Clo
} else {
out.VsphereVolume = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(QuobyteVolumeSource)
**out = **in
} else {
out.Quobyte = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(AzureDiskVolumeSource)
if err := DeepCopy_v1_AzureDiskVolumeSource(*in, *out, c); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
}

View file

@ -0,0 +1,80 @@
/*
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 (
"fmt"
"k8s.io/client-go/1.4/pkg/api"
"k8s.io/client-go/1.4/pkg/api/meta"
"k8s.io/client-go/1.4/pkg/api/unversioned"
apiutil "k8s.io/client-go/1.4/pkg/api/util"
"k8s.io/client-go/1.4/pkg/apimachinery/registered"
"k8s.io/client-go/1.4/pkg/util/validation"
"k8s.io/client-go/1.4/pkg/util/validation/field"
)
// ValidateEvent makes sure that the event makes sense.
func ValidateEvent(event *api.Event) field.ErrorList {
allErrs := field.ErrorList{}
// Make sure event.Namespace and the involvedObject.Namespace agree
if len(event.InvolvedObject.Namespace) == 0 {
// event.Namespace must also be empty (or "default", for compatibility with old clients)
if event.Namespace != api.NamespaceNone && event.Namespace != api.NamespaceDefault {
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
}
} else {
// event namespace must match
if event.Namespace != event.InvolvedObject.Namespace {
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
}
}
// For kinds we recognize, make sure involvedObject.Namespace is set for namespaced kinds
if namespaced, err := isNamespacedKind(event.InvolvedObject.Kind, event.InvolvedObject.APIVersion); err == nil {
if namespaced && len(event.InvolvedObject.Namespace) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("involvedObject", "namespace"), fmt.Sprintf("required for kind %s", event.InvolvedObject.Kind)))
}
if !namespaced && len(event.InvolvedObject.Namespace) > 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, fmt.Sprintf("not allowed for kind %s", event.InvolvedObject.Kind)))
}
}
for _, msg := range validation.IsDNS1123Subdomain(event.Namespace) {
allErrs = append(allErrs, field.Invalid(field.NewPath("namespace"), event.Namespace, msg))
}
return allErrs
}
// Check whether the kind in groupVersion is scoped at the root of the api hierarchy
func isNamespacedKind(kind, groupVersion string) (bool, error) {
group := apiutil.GetGroup(groupVersion)
g, err := registered.Group(group)
if err != nil {
return false, err
}
restMapping, err := g.RESTMapper.RESTMapping(unversioned.GroupKind{Group: group, Kind: kind}, apiutil.GetVersion(groupVersion))
if err != nil {
return false, err
}
scopeName := restMapping.Scope.Name()
if scopeName == meta.RESTScopeNameNamespace {
return true, nil
}
return false, nil
}

View file

@ -23,6 +23,7 @@ import (
"os"
"path"
"reflect"
"regexp"
"strings"
"github.com/golang/glog"
@ -36,6 +37,8 @@ import (
"k8s.io/client-go/1.4/pkg/api/v1"
"k8s.io/client-go/1.4/pkg/capabilities"
"k8s.io/client-go/1.4/pkg/labels"
"k8s.io/client-go/1.4/pkg/security/apparmor"
utilconfig "k8s.io/client-go/1.4/pkg/util/config"
"k8s.io/client-go/1.4/pkg/util/intstr"
"k8s.io/client-go/1.4/pkg/util/sets"
"k8s.io/client-go/1.4/pkg/util/validation"
@ -52,6 +55,7 @@ const fieldImmutableErrorMsg string = `field is immutable`
const isNotIntegerErrorMsg string = `must be an integer`
var pdPartitionErrorMsg string = validation.InclusiveRangeError(1, 255)
var volumeModeErrorMsg string = "must be a number between 0 and 0777 (octal), both inclusive"
const totalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
@ -100,7 +104,16 @@ func ValidateDNS1123Label(value string, fldPath *field.Path) field.ErrorList {
return allErrs
}
func ValidatePodSpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
// ValidateDNS1123Subdomain validates that a name is a proper DNS subdomain.
func ValidateDNS1123Subdomain(value string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, msg := range validation.IsDNS1123Subdomain(value) {
allErrs = append(allErrs, field.Invalid(fldPath, value, msg))
}
return allErrs
}
func ValidatePodSpecificAnnotations(annotations map[string]string, spec *api.PodSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if annotations[api.AffinityAnnotationKey] != "" {
allErrs = append(allErrs, ValidateAffinityInPodAnnotations(annotations, fldPath)...)
@ -119,7 +132,50 @@ func ValidatePodSpecificAnnotations(annotations map[string]string, fldPath *fiel
}
allErrs = append(allErrs, ValidateSeccompPodAnnotations(annotations, fldPath)...)
allErrs = append(allErrs, ValidateAppArmorPodAnnotations(annotations, spec, fldPath)...)
sysctls, err := api.SysctlsFromPodAnnotation(annotations[api.SysctlsPodAnnotationKey])
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.SysctlsPodAnnotationKey), annotations[api.SysctlsPodAnnotationKey], err.Error()))
} else {
allErrs = append(allErrs, validateSysctls(sysctls, fldPath.Key(api.SysctlsPodAnnotationKey))...)
}
unsafeSysctls, err := api.SysctlsFromPodAnnotation(annotations[api.UnsafeSysctlsPodAnnotationKey])
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.UnsafeSysctlsPodAnnotationKey), annotations[api.UnsafeSysctlsPodAnnotationKey], err.Error()))
} else {
allErrs = append(allErrs, validateSysctls(unsafeSysctls, fldPath.Key(api.UnsafeSysctlsPodAnnotationKey))...)
}
inBoth := sysctlIntersection(sysctls, unsafeSysctls)
if len(inBoth) > 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.UnsafeSysctlsPodAnnotationKey), strings.Join(inBoth, ", "), "can not be safe and unsafe"))
}
return allErrs
}
func ValidatePodSpecificAnnotationUpdates(newPod, oldPod *api.Pod, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
newAnnotations := newPod.Annotations
oldAnnotations := oldPod.Annotations
for k, oldVal := range oldAnnotations {
if newAnnotations[k] == oldVal {
continue // No change.
}
if strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) {
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not update AppArmor annotations"))
}
}
// Check for removals.
for k := range newAnnotations {
if _, ok := oldAnnotations[k]; ok {
continue // No change.
}
if strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) {
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not remove AppArmor annotations"))
}
}
allErrs = append(allErrs, ValidatePodSpecificAnnotations(newAnnotations, &newPod.Spec, fldPath)...)
return allErrs
}
@ -242,6 +298,9 @@ var ValidateServiceAccountName = NameIsDNSSubdomain
// trailing dashes are allowed.
var ValidateEndpointsName = NameIsDNSSubdomain
// ValidateClusterName can be used to check whether the given cluster name is valid.
var ValidateClusterName = NameIsDNS1035Label
// NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain.
func NameIsDNSSubdomain(name string, prefix bool) []string {
if prefix {
@ -306,7 +365,7 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val
}
// If the generated name validates, but the calculated value does not, it's a problem with generation, and we
// report it here. This may confuse users, but indicates a programming bug and still must be validated.
// If there are multiple fields out of which one is required then add a or as a separator
// If there are multiple fields out of which one is required then add an or as a separator
if len(meta.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "name or generateName is required"))
} else {
@ -327,6 +386,11 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val
allErrs = append(allErrs, field.Forbidden(fldPath.Child("namespace"), "not allowed on this type"))
}
}
if len(meta.ClusterName) != 0 {
for _, msg := range ValidateClusterName(meta.ClusterName, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterName"), meta.ClusterName, msg))
}
}
allErrs = append(allErrs, ValidateNonnegativeField(meta.Generation, fldPath.Child("generation"))...)
allErrs = append(allErrs, unversionedvalidation.ValidateLabels(meta.Labels, fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(meta.Annotations, fldPath.Child("annotations"))...)
@ -388,6 +452,7 @@ func ValidateObjectMetaUpdate(newMeta, oldMeta *api.ObjectMeta, fldPath *field.P
allErrs = append(allErrs, ValidateImmutableField(newMeta.Namespace, oldMeta.Namespace, fldPath.Child("namespace"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.UID, oldMeta.UID, fldPath.Child("uid"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.CreationTimestamp, oldMeta.CreationTimestamp, fldPath.Child("creationTimestamp"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.ClusterName, oldMeta.ClusterName, fldPath.Child("clusterName"))...)
allErrs = append(allErrs, unversionedvalidation.ValidateLabels(newMeta.Labels, fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(newMeta.Annotations, fldPath.Child("annotations"))...)
@ -533,6 +598,14 @@ func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path) field.E
allErrs = append(allErrs, validateCephFSVolumeSource(source.CephFS, fldPath.Child("cephfs"))...)
}
}
if source.Quobyte != nil {
if numVolumes > 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("quobyte"), "may not specify more than 1 volume type"))
} else {
numVolumes++
allErrs = append(allErrs, validateQuobyteVolumeSource(source.Quobyte, fldPath.Child("quobyte"))...)
}
}
if source.DownwardAPI != nil {
if numVolumes > 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("downwarAPI"), "may not specify more than 1 volume type"))
@ -551,7 +624,7 @@ func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path) field.E
}
if source.FlexVolume != nil {
if numVolumes > 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("flexVolume"), "may not specifiy more than 1 volume type"))
allErrs = append(allErrs, field.Forbidden(fldPath.Child("flexVolume"), "may not specify more than 1 volume type"))
} else {
numVolumes++
allErrs = append(allErrs, validateFlexVolumeSource(source.FlexVolume, fldPath.Child("flexVolume"))...)
@ -559,7 +632,7 @@ func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path) field.E
}
if source.ConfigMap != nil {
if numVolumes > 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("configMap"), "may not specifiy more than 1 volume type"))
allErrs = append(allErrs, field.Forbidden(fldPath.Child("configMap"), "may not specify more than 1 volume type"))
} else {
numVolumes++
allErrs = append(allErrs, validateConfigMapVolumeSource(source.ConfigMap, fldPath.Child("configMap"))...)
@ -577,6 +650,11 @@ func validateVolumeSource(source *api.VolumeSource, fldPath *field.Path) field.E
allErrs = append(allErrs, validateVsphereVolumeSource(source.VsphereVolume, fldPath.Child("vsphereVolume"))...)
}
}
if source.AzureDisk != nil {
numVolumes++
allErrs = append(allErrs, validateAzureDisk(source.AzureDisk, fldPath.Child("azureDisk"))...)
}
if numVolumes == 0 {
allErrs = append(allErrs, field.Required(fldPath, "must specify a volume type"))
}
@ -660,6 +738,12 @@ func validateSecretVolumeSource(secretSource *api.SecretVolumeSource, fldPath *f
if len(secretSource.SecretName) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("secretName"), ""))
}
secretMode := secretSource.DefaultMode
if secretMode != nil && (*secretMode > 0777 || *secretMode < 0) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("defaultMode"), *secretMode, volumeModeErrorMsg))
}
itemsPath := fldPath.Child("items")
for i, kp := range secretSource.Items {
itemPath := itemsPath.Index(i)
@ -673,6 +757,12 @@ func validateConfigMapVolumeSource(configMapSource *api.ConfigMapVolumeSource, f
if len(configMapSource.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
}
configMapMode := configMapSource.DefaultMode
if configMapMode != nil && (*configMapMode > 0777 || *configMapMode < 0) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("defaultMode"), *configMapMode, volumeModeErrorMsg))
}
itemsPath := fldPath.Child("items")
for i, kp := range configMapSource.Items {
itemPath := itemsPath.Index(i)
@ -690,6 +780,10 @@ func validateKeyToPath(kp *api.KeyToPath, fldPath *field.Path) field.ErrorList {
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
}
allErrs = append(allErrs, validateLocalNonReservedPath(kp.Path, fldPath.Child("path"))...)
if kp.Mode != nil && (*kp.Mode > 0777 || *kp.Mode < 0) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("mode"), *kp.Mode, volumeModeErrorMsg))
}
return allErrs
}
@ -715,6 +809,24 @@ func validateNFSVolumeSource(nfs *api.NFSVolumeSource, fldPath *field.Path) fiel
return allErrs
}
func validateQuobyteVolumeSource(quobyte *api.QuobyteVolumeSource, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(quobyte.Registry) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("registry"), "must be a host:port pair or multiple pairs separated by commas"))
} else {
for _, hostPortPair := range strings.Split(quobyte.Registry, ",") {
if _, _, err := net.SplitHostPort(hostPortPair); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("registry"), quobyte.Registry, "must be a host:port pair or multiple pairs separated by commas"))
}
}
}
if len(quobyte.Volume) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("volume"), ""))
}
return allErrs
}
func validateGlusterfs(glusterfs *api.GlusterfsVolumeSource, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(glusterfs.EndpointsName) == 0 {
@ -745,6 +857,12 @@ var validDownwardAPIFieldPathExpressions = sets.NewString(
func validateDownwardAPIVolumeSource(downwardAPIVolume *api.DownwardAPIVolumeSource, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
downwardAPIMode := downwardAPIVolume.DefaultMode
if downwardAPIMode != nil && (*downwardAPIMode > 0777 || *downwardAPIMode < 0) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("defaultMode"), *downwardAPIMode, volumeModeErrorMsg))
}
for _, file := range downwardAPIVolume.Items {
if len(file.Path) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
@ -760,6 +878,9 @@ func validateDownwardAPIVolumeSource(downwardAPIVolume *api.DownwardAPIVolumeSou
} else {
allErrs = append(allErrs, field.Required(fldPath, "one of fieldRef and resourceFieldRef is required"))
}
if file.Mode != nil && (*file.Mode > 0777 || *file.Mode < 0) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("mode"), *file.Mode, volumeModeErrorMsg))
}
}
return allErrs
}
@ -844,6 +965,22 @@ func validateAzureFile(azure *api.AzureFileVolumeSource, fldPath *field.Path) fi
return allErrs
}
var supportedCachingModes = sets.NewString(string(api.AzureDataDiskCachingNone), string(api.AzureDataDiskCachingReadOnly), string(api.AzureDataDiskCachingReadWrite))
func validateAzureDisk(azure *api.AzureDiskVolumeSource, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if azure.DiskName == "" {
allErrs = append(allErrs, field.Required(fldPath.Child("diskName"), ""))
}
if azure.DataDiskURI == "" {
allErrs = append(allErrs, field.Required(fldPath.Child("diskURI"), ""))
}
if azure.CachingMode != nil && !supportedCachingModes.Has(string(*azure.CachingMode)) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("cachingMode"), *azure.CachingMode, supportedCachingModes.List()))
}
return allErrs
}
func validateVsphereVolumeSource(cd *api.VsphereVirtualDiskVolumeSource, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(cd.VolumePath) == 0 {
@ -858,6 +995,8 @@ var ValidatePersistentVolumeName = NameIsDNSSubdomain
var supportedAccessModes = sets.NewString(string(api.ReadWriteOnce), string(api.ReadOnlyMany), string(api.ReadWriteMany))
var supportedReclaimPolicy = sets.NewString(string(api.PersistentVolumeReclaimDelete), string(api.PersistentVolumeReclaimRecycle), string(api.PersistentVolumeReclaimRetain))
func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
allErrs := ValidateObjectMeta(&pv.ObjectMeta, false, ValidatePersistentVolumeName, field.NewPath("metadata"))
@ -882,6 +1021,11 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
for r, qty := range pv.Spec.Capacity {
allErrs = append(allErrs, validateBasicResource(qty, capPath.Key(string(r)))...)
}
if len(string(pv.Spec.PersistentVolumeReclaimPolicy)) > 0 {
if !supportedReclaimPolicy.Has(string(pv.Spec.PersistentVolumeReclaimPolicy)) {
allErrs = append(allErrs, field.NotSupported(specPath.Child("persistentVolumeReclaimPolicy"), pv.Spec.PersistentVolumeReclaimPolicy, supportedReclaimPolicy.List()))
}
}
numVolumes := 0
if pv.Spec.HostPath != nil {
@ -940,6 +1084,14 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
allErrs = append(allErrs, validateRBDVolumeSource(pv.Spec.RBD, specPath.Child("rbd"))...)
}
}
if pv.Spec.Quobyte != nil {
if numVolumes > 0 {
allErrs = append(allErrs, field.Forbidden(specPath.Child("quobyte"), "may not specify more than 1 volume type"))
} else {
numVolumes++
allErrs = append(allErrs, validateQuobyteVolumeSource(pv.Spec.Quobyte, specPath.Child("quobyte"))...)
}
}
if pv.Spec.CephFS != nil {
if numVolumes > 0 {
allErrs = append(allErrs, field.Forbidden(specPath.Child("cephFS"), "may not specify more than 1 volume type"))
@ -988,9 +1140,20 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
allErrs = append(allErrs, validateVsphereVolumeSource(pv.Spec.VsphereVolume, specPath.Child("vsphereVolume"))...)
}
}
if pv.Spec.AzureDisk != nil {
numVolumes++
allErrs = append(allErrs, validateAzureDisk(pv.Spec.AzureDisk, specPath.Child("azureDisk"))...)
}
if numVolumes == 0 {
allErrs = append(allErrs, field.Required(specPath, "must specify a volume type"))
}
// do not allow hostPath mounts of '/' to have a 'recycle' reclaim policy
if pv.Spec.HostPath != nil && path.Clean(pv.Spec.HostPath.Path) == "/" && pv.Spec.PersistentVolumeReclaimPolicy == api.PersistentVolumeReclaimRecycle {
allErrs = append(allErrs, field.Forbidden(specPath.Child("persistentVolumeReclaimPolicy"), "may not be 'recycle' for a hostPath mount of '/'"))
}
return allErrs
}
@ -1014,26 +1177,37 @@ func ValidatePersistentVolumeStatusUpdate(newPv, oldPv *api.PersistentVolume) fi
return allErrs
}
// ValidatePersistentVolumeClaim validates a PersistentVolumeClaim
func ValidatePersistentVolumeClaim(pvc *api.PersistentVolumeClaim) field.ErrorList {
allErrs := ValidateObjectMeta(&pvc.ObjectMeta, true, ValidatePersistentVolumeName, field.NewPath("metadata"))
specPath := field.NewPath("spec")
if len(pvc.Spec.AccessModes) == 0 {
allErrs = append(allErrs, field.Required(specPath.Child("accessModes"), "at least 1 accessMode is required"))
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&pvc.Spec, field.NewPath("spec"))...)
return allErrs
}
// ValidatePersistentVolumeClaimSpec validates a PersistentVolumeClaimSpec
func ValidatePersistentVolumeClaimSpec(spec *api.PersistentVolumeClaimSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(spec.AccessModes) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("accessModes"), "at least 1 access mode is required"))
}
if pvc.Spec.Selector != nil {
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(pvc.Spec.Selector, specPath.Child("selector"))...)
if spec.Selector != nil {
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
}
for _, mode := range pvc.Spec.AccessModes {
for _, mode := range spec.AccessModes {
if mode != api.ReadWriteOnce && mode != api.ReadOnlyMany && mode != api.ReadWriteMany {
allErrs = append(allErrs, field.NotSupported(specPath.Child("accessModes"), mode, supportedAccessModes.List()))
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, supportedAccessModes.List()))
}
}
if _, ok := pvc.Spec.Resources.Requests[api.ResourceStorage]; !ok {
allErrs = append(allErrs, field.Required(specPath.Child("resources").Key(string(api.ResourceStorage)), ""))
storageValue, ok := spec.Resources.Requests[api.ResourceStorage]
if !ok {
allErrs = append(allErrs, field.Required(fldPath.Child("resources").Key(string(api.ResourceStorage)), ""))
} else {
allErrs = append(allErrs, ValidateResourceQuantityValue(string(api.ResourceStorage), storageValue, fldPath.Child("resources").Key(string(api.ResourceStorage)))...)
}
return allErrs
}
// ValidatePersistentVolumeClaimUpdate validates an update to a PeristentVolumeClaim
func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *api.PersistentVolumeClaim) field.ErrorList {
allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
allErrs = append(allErrs, ValidatePersistentVolumeClaim(newPvc)...)
@ -1054,6 +1228,7 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *api.PersistentVolumeCla
return allErrs
}
// ValidatePersistentVolumeClaimStatusUpdate validates an update to status of a PeristentVolumeClaim
func ValidatePersistentVolumeClaimStatusUpdate(newPvc, oldPvc *api.PersistentVolumeClaim) field.ErrorList {
allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
if len(newPvc.ResourceVersion) == 0 {
@ -1127,7 +1302,7 @@ func validateEnv(vars []api.EnvVar, fldPath *field.Path) field.ErrorList {
return allErrs
}
var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "status.podIP")
var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "spec.nodeName", "spec.serviceAccountName", "status.podIP")
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "requests.cpu", "requests.memory")
func validateEnvVarValueFrom(ev api.EnvVar, fldPath *field.Path) field.ErrorList {
@ -1636,7 +1811,7 @@ func validateTolerations(tolerations []api.Toleration, fldPath *field.Path) fiel
func ValidatePod(pod *api.Pod) field.ErrorList {
fldPath := field.NewPath("metadata")
allErrs := ValidateObjectMeta(&pod.ObjectMeta, true, ValidatePodName, fldPath)
allErrs = append(allErrs, ValidatePodSpecificAnnotations(pod.ObjectMeta.Annotations, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpecificAnnotations(pod.ObjectMeta.Annotations, &pod.Spec, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpec(&pod.Spec, field.NewPath("spec"))...)
return allErrs
}
@ -1952,6 +2127,77 @@ func ValidateSeccompPodAnnotations(annotations map[string]string, fldPath *field
return allErrs
}
func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *api.PodSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for k, p := range annotations {
if !strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) {
continue
}
if !utilconfig.DefaultFeatureGate.AppArmor() {
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "AppArmor is disabled by feature-gate"))
continue
}
containerName := strings.TrimPrefix(k, apparmor.ContainerAnnotationKeyPrefix)
if !podSpecHasContainer(spec, containerName) {
allErrs = append(allErrs, field.Invalid(fldPath.Key(k), containerName, "container not found"))
}
if err := apparmor.ValidateProfileFormat(p); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Key(k), p, err.Error()))
}
}
return allErrs
}
func podSpecHasContainer(spec *api.PodSpec, containerName string) bool {
for _, c := range spec.InitContainers {
if c.Name == containerName {
return true
}
}
for _, c := range spec.Containers {
if c.Name == containerName {
return true
}
}
return false
}
const (
// a sysctl segment regex, concatenated with dots to form a sysctl name
SysctlSegmentFmt string = "[a-z0-9]([-_a-z0-9]*[a-z0-9])?"
// a sysctl name regex
SysctlFmt string = "(" + SysctlSegmentFmt + "\\.)*" + SysctlSegmentFmt
// the maximal length of a sysctl name
SysctlMaxLength int = 253
)
var sysctlRegexp = regexp.MustCompile("^" + SysctlFmt + "$")
// IsValidSysctlName checks that the given string is a valid sysctl name,
// i.e. matches SysctlFmt.
func IsValidSysctlName(name string) bool {
if len(name) > SysctlMaxLength {
return false
}
return sysctlRegexp.MatchString(name)
}
func validateSysctls(sysctls []api.Sysctl, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for i, s := range sysctls {
if len(s.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Index(i).Child("name"), ""))
} else if !IsValidSysctlName(s.Name) {
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("name"), s.Name, fmt.Sprintf("must have at most %d characters and match regex %s", SysctlMaxLength, SysctlFmt)))
}
}
return allErrs
}
// ValidatePodSecurityContext test that the specified PodSecurityContext has valid data.
func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *api.PodSpec, specPath, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
@ -1978,7 +2224,7 @@ func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *a
return allErrs
}
func validateContainerUpdates(newContainers, oldContainers []api.Container, fldPath *field.Path) (allErrs field.ErrorList, stop bool) {
func ValidateContainerUpdates(newContainers, oldContainers []api.Container, fldPath *field.Path) (allErrs field.ErrorList, stop bool) {
allErrs = field.ErrorList{}
if len(newContainers) != len(oldContainers) {
//TODO: Pinpoint the specific container that causes the invalid error after we have strategic merge diff
@ -2000,7 +2246,7 @@ func validateContainerUpdates(newContainers, oldContainers []api.Container, fldP
func ValidatePodUpdate(newPod, oldPod *api.Pod) field.ErrorList {
fldPath := field.NewPath("metadata")
allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, &oldPod.ObjectMeta, fldPath)
allErrs = append(allErrs, ValidatePodSpecificAnnotations(newPod.ObjectMeta.Annotations, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"))...)
specPath := field.NewPath("spec")
// validate updateable fields:
@ -2008,12 +2254,12 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) field.ErrorList {
// 2. initContainers[*].image
// 3. spec.activeDeadlineSeconds
containerErrs, stop := validateContainerUpdates(newPod.Spec.Containers, oldPod.Spec.Containers, specPath.Child("containers"))
containerErrs, stop := ValidateContainerUpdates(newPod.Spec.Containers, oldPod.Spec.Containers, specPath.Child("containers"))
allErrs = append(allErrs, containerErrs...)
if stop {
return allErrs
}
containerErrs, stop = validateContainerUpdates(newPod.Spec.InitContainers, oldPod.Spec.InitContainers, specPath.Child("initContainers"))
containerErrs, stop = ValidateContainerUpdates(newPod.Spec.InitContainers, oldPod.Spec.InitContainers, specPath.Child("initContainers"))
allErrs = append(allErrs, containerErrs...)
if stop {
return allErrs
@ -2118,17 +2364,19 @@ func ValidatePodTemplateUpdate(newPod, oldPod *api.PodTemplate) field.ErrorList
var supportedSessionAffinityType = sets.NewString(string(api.ServiceAffinityClientIP), string(api.ServiceAffinityNone))
var supportedServiceType = sets.NewString(string(api.ServiceTypeClusterIP), string(api.ServiceTypeNodePort),
string(api.ServiceTypeLoadBalancer))
string(api.ServiceTypeLoadBalancer), string(api.ServiceTypeExternalName))
// ValidateService tests if required fields in the service are set.
func ValidateService(service *api.Service) field.ErrorList {
allErrs := ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName, field.NewPath("metadata"))
specPath := field.NewPath("spec")
if len(service.Spec.Ports) == 0 && service.Spec.ClusterIP != api.ClusterIPNone {
isHeadlessService := service.Spec.ClusterIP == api.ClusterIPNone
if len(service.Spec.Ports) == 0 && !isHeadlessService && service.Spec.Type != api.ServiceTypeExternalName {
allErrs = append(allErrs, field.Required(specPath.Child("ports"), ""))
}
if service.Spec.Type == api.ServiceTypeLoadBalancer {
switch service.Spec.Type {
case api.ServiceTypeLoadBalancer:
for ix := range service.Spec.Ports {
port := &service.Spec.Ports[ix]
// This is a workaround for broken cloud environments that
@ -2139,9 +2387,17 @@ func ValidateService(service *api.Service) field.ErrorList {
allErrs = append(allErrs, field.Invalid(portPath, port.Port, "may not expose port 10250 externally since it is used by kubelet"))
}
}
case api.ServiceTypeExternalName:
if service.Spec.ClusterIP != "" {
allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty for ExternalName services"))
}
if len(service.Spec.ExternalName) > 0 {
allErrs = append(allErrs, ValidateDNS1123Subdomain(service.Spec.ExternalName, specPath.Child("externalName"))...)
} else {
allErrs = append(allErrs, field.Required(specPath.Child("externalName"), ""))
}
}
isHeadlessService := service.Spec.ClusterIP == api.ClusterIPNone
allPortNames := sets.String{}
portsPath := specPath.Child("ports")
for i := range service.Spec.Ports {
@ -2382,7 +2638,7 @@ func ValidatePodTemplateSpec(spec *api.PodTemplateSpec, fldPath *field.Path) fie
allErrs := field.ErrorList{}
allErrs = append(allErrs, unversionedvalidation.ValidateLabels(spec.Labels, fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(spec.Annotations, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpecificAnnotations(spec.Annotations, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpecificAnnotations(spec.Annotations, &spec.Spec, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpec(&spec.Spec, fldPath.Child("spec"))...)
return allErrs
}
@ -2405,6 +2661,9 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume, fldPath *field.Path)
// validateTaints tests if given taints have valid data.
func validateTaints(taints []api.Taint, fldPath *field.Path) field.ErrorList {
allErrors := field.ErrorList{}
uniqueTaints := map[api.TaintEffect]sets.String{}
for i, currTaint := range taints {
idxPath := fldPath.Index(i)
// validate the taint key
@ -2415,6 +2674,20 @@ func validateTaints(taints []api.Taint, fldPath *field.Path) field.ErrorList {
}
// validate the taint effect
allErrors = append(allErrors, validateTaintEffect(&currTaint.Effect, false, idxPath.Child("effect"))...)
// validate if taint is unique by <key, effect>
if len(uniqueTaints[currTaint.Effect]) > 0 && uniqueTaints[currTaint.Effect].Has(currTaint.Key) {
duplicatedError := field.Duplicate(idxPath, currTaint)
duplicatedError.Detail = "taints must be unique by key and effect pair"
allErrors = append(allErrors, duplicatedError)
continue
}
// add taint to existingTaints for uniqueness check
if len(uniqueTaints[currTaint.Effect]) == 0 {
uniqueTaints[currTaint.Effect] = sets.String{}
}
uniqueTaints[currTaint.Effect].Insert(currTaint.Key)
}
return allErrors
}
@ -3085,17 +3358,50 @@ func ValidateNamespaceFinalizeUpdate(newNamespace, oldNamespace *api.Namespace)
return allErrs
}
// Construct lookup map of old subset IPs to NodeNames.
func updateEpAddrToNodeNameMap(ipToNodeName map[string]string, addresses []api.EndpointAddress) {
for n := range addresses {
if addresses[n].NodeName == nil {
continue
}
ipToNodeName[addresses[n].IP] = *addresses[n].NodeName
}
}
// Build a map across all subsets of IP -> NodeName
func buildEndpointAddressNodeNameMap(subsets []api.EndpointSubset) map[string]string {
ipToNodeName := make(map[string]string)
for i := range subsets {
updateEpAddrToNodeNameMap(ipToNodeName, subsets[i].Addresses)
updateEpAddrToNodeNameMap(ipToNodeName, subsets[i].NotReadyAddresses)
}
return ipToNodeName
}
func validateEpAddrNodeNameTransition(addr *api.EndpointAddress, ipToNodeName map[string]string, fldPath *field.Path) field.ErrorList {
errList := field.ErrorList{}
existingNodeName, found := ipToNodeName[addr.IP]
if !found {
return errList
}
if addr.NodeName == nil || *addr.NodeName == existingNodeName {
return errList
}
// NodeName entry found for this endpoint IP, but user is attempting to change NodeName
return append(errList, field.Forbidden(fldPath, fmt.Sprintf("Cannot change NodeName for %s to %s", addr.IP, *addr.NodeName)))
}
// ValidateEndpoints tests if required fields are set.
func ValidateEndpoints(endpoints *api.Endpoints) field.ErrorList {
allErrs := ValidateObjectMeta(&endpoints.ObjectMeta, true, ValidateEndpointsName, field.NewPath("metadata"))
allErrs = append(allErrs, ValidateEndpointsSpecificAnnotations(endpoints.Annotations, field.NewPath("annotations"))...)
allErrs = append(allErrs, validateEndpointSubsets(endpoints.Subsets, field.NewPath("subsets"))...)
allErrs = append(allErrs, validateEndpointSubsets(endpoints.Subsets, []api.EndpointSubset{}, field.NewPath("subsets"))...)
return allErrs
}
func validateEndpointSubsets(subsets []api.EndpointSubset, fldPath *field.Path) field.ErrorList {
func validateEndpointSubsets(subsets []api.EndpointSubset, oldSubsets []api.EndpointSubset, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
ipToNodeName := buildEndpointAddressNodeNameMap(oldSubsets)
for i := range subsets {
ss := &subsets[i]
idxPath := fldPath.Index(i)
@ -3108,10 +3414,10 @@ func validateEndpointSubsets(subsets []api.EndpointSubset, fldPath *field.Path)
allErrs = append(allErrs, field.Required(idxPath.Child("ports"), ""))
}
for addr := range ss.Addresses {
allErrs = append(allErrs, validateEndpointAddress(&ss.Addresses[addr], idxPath.Child("addresses").Index(addr))...)
allErrs = append(allErrs, validateEndpointAddress(&ss.Addresses[addr], idxPath.Child("addresses").Index(addr), ipToNodeName)...)
}
for addr := range ss.NotReadyAddresses {
allErrs = append(allErrs, validateEndpointAddress(&ss.NotReadyAddresses[addr], idxPath.Child("notReadyAddresses").Index(addr))...)
allErrs = append(allErrs, validateEndpointAddress(&ss.NotReadyAddresses[addr], idxPath.Child("notReadyAddresses").Index(addr), ipToNodeName)...)
}
for port := range ss.Ports {
allErrs = append(allErrs, validateEndpointPort(&ss.Ports[port], len(ss.Ports) > 1, idxPath.Child("ports").Index(port))...)
@ -3121,7 +3427,7 @@ func validateEndpointSubsets(subsets []api.EndpointSubset, fldPath *field.Path)
return allErrs
}
func validateEndpointAddress(address *api.EndpointAddress, fldPath *field.Path) field.ErrorList {
func validateEndpointAddress(address *api.EndpointAddress, fldPath *field.Path, ipToNodeName map[string]string) field.ErrorList {
allErrs := field.ErrorList{}
for _, msg := range validation.IsValidIP(address.IP) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("ip"), address.IP, msg))
@ -3129,6 +3435,13 @@ func validateEndpointAddress(address *api.EndpointAddress, fldPath *field.Path)
if len(address.Hostname) > 0 {
allErrs = append(allErrs, ValidateDNS1123Label(address.Hostname, fldPath.Child("hostname"))...)
}
// During endpoint update, verify that NodeName is a DNS subdomain and transition rules allow the update
if address.NodeName != nil {
for _, msg := range ValidateNodeName(*address.NodeName, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("nodeName"), *address.NodeName, msg))
}
}
allErrs = append(allErrs, validateEpAddrNodeNameTransition(address, ipToNodeName, fldPath.Child("nodeName"))...)
if len(allErrs) > 0 {
return allErrs
}
@ -3183,7 +3496,7 @@ func validateEndpointPort(port *api.EndpointPort, requireName bool, fldPath *fie
// ValidateEndpointsUpdate tests to make sure an endpoints update can be applied.
func ValidateEndpointsUpdate(newEndpoints, oldEndpoints *api.Endpoints) field.ErrorList {
allErrs := ValidateObjectMetaUpdate(&newEndpoints.ObjectMeta, &oldEndpoints.ObjectMeta, field.NewPath("metadata"))
allErrs = append(allErrs, validateEndpointSubsets(newEndpoints.Subsets, field.NewPath("subsets"))...)
allErrs = append(allErrs, validateEndpointSubsets(newEndpoints.Subsets, oldEndpoints.Subsets, field.NewPath("subsets"))...)
allErrs = append(allErrs, ValidateEndpointsSpecificAnnotations(newEndpoints.Annotations, field.NewPath("annotations"))...)
return allErrs
}
@ -3272,3 +3585,17 @@ func isValidHostnamesMap(serializedPodHostNames string) bool {
}
return true
}
func sysctlIntersection(a []api.Sysctl, b []api.Sysctl) []string {
lookup := make(map[string]struct{}, len(a))
result := []string{}
for i := range a {
lookup[a[i].Name] = struct{}{}
}
for i := range b {
if _, found := lookup[b[i].Name]; found {
result = append(result, b[i].Name)
}
}
return result
}

View file

@ -42,6 +42,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Affinity, InType: reflect.TypeOf(&Affinity{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_AttachedVolume, InType: reflect.TypeOf(&AttachedVolume{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_AvoidPods, InType: reflect.TypeOf(&AvoidPods{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_AzureDiskVolumeSource, InType: reflect.TypeOf(&AzureDiskVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_AzureFileVolumeSource, InType: reflect.TypeOf(&AzureFileVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Binding, InType: reflect.TypeOf(&Binding{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Capabilities, InType: reflect.TypeOf(&Capabilities{})},
@ -157,6 +158,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PreferAvoidPodsEntry, InType: reflect.TypeOf(&PreferAvoidPodsEntry{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PreferredSchedulingTerm, InType: reflect.TypeOf(&PreferredSchedulingTerm{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Probe, InType: reflect.TypeOf(&Probe{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_QuobyteVolumeSource, InType: reflect.TypeOf(&QuobyteVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_RBDVolumeSource, InType: reflect.TypeOf(&RBDVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_RangeAllocation, InType: reflect.TypeOf(&RangeAllocation{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ReplicationController, InType: reflect.TypeOf(&ReplicationController{})},
@ -184,6 +186,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ServiceProxyOptions, InType: reflect.TypeOf(&ServiceProxyOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ServiceSpec, InType: reflect.TypeOf(&ServiceSpec{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ServiceStatus, InType: reflect.TypeOf(&ServiceStatus{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Sysctl, InType: reflect.TypeOf(&Sysctl{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_TCPSocketAction, InType: reflect.TypeOf(&TCPSocketAction{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Taint, InType: reflect.TypeOf(&Taint{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_Toleration, InType: reflect.TypeOf(&Toleration{})},
@ -271,6 +274,37 @@ func DeepCopy_api_AvoidPods(in interface{}, out interface{}, c *conversion.Clone
}
}
func DeepCopy_api_AzureDiskVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*AzureDiskVolumeSource)
out := out.(*AzureDiskVolumeSource)
out.DiskName = in.DiskName
out.DataDiskURI = in.DataDiskURI
if in.CachingMode != nil {
in, out := &in.CachingMode, &out.CachingMode
*out = new(AzureDataDiskCachingMode)
**out = **in
} else {
out.CachingMode = nil
}
if in.FSType != nil {
in, out := &in.FSType, &out.FSType
*out = new(string)
**out = **in
} else {
out.FSType = nil
}
if in.ReadOnly != nil {
in, out := &in.ReadOnly, &out.ReadOnly
*out = new(bool)
**out = **in
} else {
out.ReadOnly = nil
}
return nil
}
}
func DeepCopy_api_AzureFileVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*AzureFileVolumeSource)
@ -473,11 +507,20 @@ func DeepCopy_api_ConfigMapVolumeSource(in interface{}, out interface{}, c *conv
in, out := &in.Items, &out.Items
*out = make([]KeyToPath, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
if err := DeepCopy_api_KeyToPath(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
if in.DefaultMode != nil {
in, out := &in.DefaultMode, &out.DefaultMode
*out = new(int32)
**out = **in
} else {
out.DefaultMode = nil
}
return nil
}
}
@ -781,6 +824,13 @@ func DeepCopy_api_DownwardAPIVolumeFile(in interface{}, out interface{}, c *conv
} else {
out.ResourceFieldRef = nil
}
if in.Mode != nil {
in, out := &in.Mode, &out.Mode
*out = new(int32)
**out = **in
} else {
out.Mode = nil
}
return nil
}
}
@ -800,6 +850,13 @@ func DeepCopy_api_DownwardAPIVolumeSource(in interface{}, out interface{}, c *co
} else {
out.Items = nil
}
if in.DefaultMode != nil {
in, out := &in.DefaultMode, &out.DefaultMode
*out = new(int32)
**out = **in
} else {
out.DefaultMode = nil
}
return nil
}
}
@ -819,6 +876,13 @@ func DeepCopy_api_EndpointAddress(in interface{}, out interface{}, c *conversion
out := out.(*EndpointAddress)
out.IP = in.IP
out.Hostname = in.Hostname
if in.NodeName != nil {
in, out := &in.NodeName, &out.NodeName
*out = new(string)
**out = **in
} else {
out.NodeName = nil
}
if in.TargetRef != nil {
in, out := &in.TargetRef, &out.TargetRef
*out = new(ObjectReference)
@ -1245,6 +1309,13 @@ func DeepCopy_api_KeyToPath(in interface{}, out interface{}, c *conversion.Clone
out := out.(*KeyToPath)
out.Key = in.Key
out.Path = in.Path
if in.Mode != nil {
in, out := &in.Mode, &out.Mode
*out = new(int32)
**out = **in
} else {
out.Mode = nil
}
return nil
}
}
@ -1909,6 +1980,7 @@ func DeepCopy_api_ObjectMeta(in interface{}, out interface{}, c *conversion.Clon
} else {
out.Finalizers = nil
}
out.ClusterName = in.ClusterName
return nil
}
}
@ -2138,6 +2210,13 @@ func DeepCopy_api_PersistentVolumeSource(in interface{}, out interface{}, c *con
} else {
out.RBD = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(QuobyteVolumeSource)
**out = **in
} else {
out.Quobyte = nil
}
if in.ISCSI != nil {
in, out := &in.ISCSI, &out.ISCSI
*out = new(ISCSIVolumeSource)
@ -2200,6 +2279,15 @@ func DeepCopy_api_PersistentVolumeSource(in interface{}, out interface{}, c *con
} else {
out.VsphereVolume = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(AzureDiskVolumeSource)
if err := DeepCopy_api_AzureDiskVolumeSource(*in, *out, c); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
}
@ -2802,6 +2890,19 @@ func DeepCopy_api_Probe(in interface{}, out interface{}, c *conversion.Cloner) e
}
}
func DeepCopy_api_QuobyteVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*QuobyteVolumeSource)
out := out.(*QuobyteVolumeSource)
out.Registry = in.Registry
out.Volume = in.Volume
out.ReadOnly = in.ReadOnly
out.User = in.User
out.Group = in.Group
return nil
}
}
func DeepCopy_api_RBDVolumeSource(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RBDVolumeSource)
@ -2920,6 +3021,7 @@ func DeepCopy_api_ReplicationControllerStatus(in interface{}, out interface{}, c
out := out.(*ReplicationControllerStatus)
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
out.ObservedGeneration = in.ObservedGeneration
return nil
}
@ -3131,11 +3233,20 @@ func DeepCopy_api_SecretVolumeSource(in interface{}, out interface{}, c *convers
in, out := &in.Items, &out.Items
*out = make([]KeyToPath, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
if err := DeepCopy_api_KeyToPath(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
if in.DefaultMode != nil {
in, out := &in.DefaultMode, &out.DefaultMode
*out = new(int32)
**out = **in
} else {
out.DefaultMode = nil
}
return nil
}
}
@ -3339,6 +3450,7 @@ func DeepCopy_api_ServiceSpec(in interface{}, out interface{}, c *conversion.Clo
out.Selector = nil
}
out.ClusterIP = in.ClusterIP
out.ExternalName = in.ExternalName
if in.ExternalIPs != nil {
in, out := &in.ExternalIPs, &out.ExternalIPs
*out = make([]string, len(*in))
@ -3370,6 +3482,16 @@ func DeepCopy_api_ServiceStatus(in interface{}, out interface{}, c *conversion.C
}
}
func DeepCopy_api_Sysctl(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Sysctl)
out := out.(*Sysctl)
out.Name = in.Name
out.Value = in.Value
return nil
}
}
func DeepCopy_api_TCPSocketAction(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TCPSocketAction)
@ -3511,6 +3633,13 @@ func DeepCopy_api_VolumeSource(in interface{}, out interface{}, c *conversion.Cl
} else {
out.RBD = nil
}
if in.Quobyte != nil {
in, out := &in.Quobyte, &out.Quobyte
*out = new(QuobyteVolumeSource)
**out = **in
} else {
out.Quobyte = nil
}
if in.FlexVolume != nil {
in, out := &in.FlexVolume, &out.FlexVolume
*out = new(FlexVolumeSource)
@ -3584,6 +3713,15 @@ func DeepCopy_api_VolumeSource(in interface{}, out interface{}, c *conversion.Cl
} else {
out.VsphereVolume = nil
}
if in.AzureDisk != nil {
in, out := &in.AzureDisk, &out.AzureDisk
*out = new(AzureDiskVolumeSource)
if err := DeepCopy_api_AzureDiskVolumeSource(*in, *out, c); err != nil {
return err
}
} else {
out.AzureDisk = nil
}
return nil
}
}

20
vendor/k8s.io/client-go/1.4/pkg/apimachinery/doc.go generated vendored Normal file
View file

@ -0,0 +1,20 @@
/*
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 apimachinery contains the generic API machinery code that
// is common to both server and clients.
// This package should never import specific API objects.
package apimachinery

View file

@ -0,0 +1,376 @@
/*
Copyright 2015 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 to keep track of API Versions that can be registered and are enabled in api.Scheme.
package registered
import (
"fmt"
"os"
"sort"
"strings"
"github.com/golang/glog"
"k8s.io/client-go/1.4/pkg/api/meta"
"k8s.io/client-go/1.4/pkg/api/unversioned"
"k8s.io/client-go/1.4/pkg/apimachinery"
"k8s.io/client-go/1.4/pkg/util/sets"
)
var (
DefaultAPIRegistrationManager = NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
)
// APIRegistrationManager
type APIRegistrationManager struct {
// registeredGroupVersions stores all API group versions for which RegisterGroup is called.
registeredVersions map[unversioned.GroupVersion]struct{}
// thirdPartyGroupVersions are API versions which are dynamically
// registered (and unregistered) via API calls to the apiserver
thirdPartyGroupVersions []unversioned.GroupVersion
// enabledVersions represents all enabled API versions. It should be a
// subset of registeredVersions. Please call EnableVersions() to add
// enabled versions.
enabledVersions map[unversioned.GroupVersion]struct{}
// map of group meta for all groups.
groupMetaMap map[string]*apimachinery.GroupMeta
// envRequestedVersions represents the versions requested via the
// KUBE_API_VERSIONS environment variable. The install package of each group
// checks this list before add their versions to the latest package and
// Scheme. This list is small and order matters, so represent as a slice
envRequestedVersions []unversioned.GroupVersion
}
// NewAPIRegistrationManager constructs a new manager. The argument ought to be
// the value of the KUBE_API_VERSIONS env var, or a value of this which you
// wish to test.
func NewAPIRegistrationManager(kubeAPIVersions string) (*APIRegistrationManager, error) {
m := &APIRegistrationManager{
registeredVersions: map[unversioned.GroupVersion]struct{}{},
thirdPartyGroupVersions: []unversioned.GroupVersion{},
enabledVersions: map[unversioned.GroupVersion]struct{}{},
groupMetaMap: map[string]*apimachinery.GroupMeta{},
envRequestedVersions: []unversioned.GroupVersion{},
}
if len(kubeAPIVersions) != 0 {
for _, version := range strings.Split(kubeAPIVersions, ",") {
gv, err := unversioned.ParseGroupVersion(version)
if err != nil {
return nil, fmt.Errorf("invalid api version: %s in KUBE_API_VERSIONS: %s.",
version, kubeAPIVersions)
}
m.envRequestedVersions = append(m.envRequestedVersions, gv)
}
}
return m, nil
}
func NewOrDie(kubeAPIVersions string) *APIRegistrationManager {
m, err := NewAPIRegistrationManager(kubeAPIVersions)
if err != nil {
glog.Fatalf("Could not construct version manager: %v (KUBE_API_VERSIONS=%q)", err, kubeAPIVersions)
}
return m
}
// People are calling global functions. Let them continue to do that (for now).
var (
ValidateEnvRequestedVersions = DefaultAPIRegistrationManager.ValidateEnvRequestedVersions
AllPreferredGroupVersions = DefaultAPIRegistrationManager.AllPreferredGroupVersions
RESTMapper = DefaultAPIRegistrationManager.RESTMapper
GroupOrDie = DefaultAPIRegistrationManager.GroupOrDie
AddThirdPartyAPIGroupVersions = DefaultAPIRegistrationManager.AddThirdPartyAPIGroupVersions
IsThirdPartyAPIGroupVersion = DefaultAPIRegistrationManager.IsThirdPartyAPIGroupVersion
RegisteredGroupVersions = DefaultAPIRegistrationManager.RegisteredGroupVersions
IsRegisteredVersion = DefaultAPIRegistrationManager.IsRegisteredVersion
IsRegistered = DefaultAPIRegistrationManager.IsRegistered
Group = DefaultAPIRegistrationManager.Group
EnabledVersionsForGroup = DefaultAPIRegistrationManager.EnabledVersionsForGroup
EnabledVersions = DefaultAPIRegistrationManager.EnabledVersions
IsEnabledVersion = DefaultAPIRegistrationManager.IsEnabledVersion
IsAllowedVersion = DefaultAPIRegistrationManager.IsAllowedVersion
EnableVersions = DefaultAPIRegistrationManager.EnableVersions
RegisterGroup = DefaultAPIRegistrationManager.RegisterGroup
RegisterVersions = DefaultAPIRegistrationManager.RegisterVersions
)
// RegisterVersions adds the given group versions to the list of registered group versions.
func (m *APIRegistrationManager) RegisterVersions(availableVersions []unversioned.GroupVersion) {
for _, v := range availableVersions {
m.registeredVersions[v] = struct{}{}
}
}
// RegisterGroup adds the given group to the list of registered groups.
func (m *APIRegistrationManager) RegisterGroup(groupMeta apimachinery.GroupMeta) error {
groupName := groupMeta.GroupVersion.Group
if _, found := m.groupMetaMap[groupName]; found {
return fmt.Errorf("group %v is already registered", m.groupMetaMap)
}
m.groupMetaMap[groupName] = &groupMeta
return nil
}
// EnableVersions adds the versions for the given group to the list of enabled versions.
// Note that the caller should call RegisterGroup before calling this method.
// The caller of this function is responsible to add the versions to scheme and RESTMapper.
func (m *APIRegistrationManager) EnableVersions(versions ...unversioned.GroupVersion) error {
var unregisteredVersions []unversioned.GroupVersion
for _, v := range versions {
if _, found := m.registeredVersions[v]; !found {
unregisteredVersions = append(unregisteredVersions, v)
}
m.enabledVersions[v] = struct{}{}
}
if len(unregisteredVersions) != 0 {
return fmt.Errorf("Please register versions before enabling them: %v", unregisteredVersions)
}
return nil
}
// IsAllowedVersion returns if the version is allowed by the KUBE_API_VERSIONS
// environment variable. If the environment variable is empty, then it always
// returns true.
func (m *APIRegistrationManager) IsAllowedVersion(v unversioned.GroupVersion) bool {
if len(m.envRequestedVersions) == 0 {
return true
}
for _, envGV := range m.envRequestedVersions {
if v == envGV {
return true
}
}
return false
}
// IsEnabledVersion returns if a version is enabled.
func (m *APIRegistrationManager) IsEnabledVersion(v unversioned.GroupVersion) bool {
_, found := m.enabledVersions[v]
return found
}
// EnabledVersions returns all enabled versions. Groups are randomly ordered, but versions within groups
// are priority order from best to worst
func (m *APIRegistrationManager) EnabledVersions() []unversioned.GroupVersion {
ret := []unversioned.GroupVersion{}
for _, groupMeta := range m.groupMetaMap {
ret = append(ret, groupMeta.GroupVersions...)
}
return ret
}
// EnabledVersionsForGroup returns all enabled versions for a group in order of best to worst
func (m *APIRegistrationManager) EnabledVersionsForGroup(group string) []unversioned.GroupVersion {
groupMeta, ok := m.groupMetaMap[group]
if !ok {
return []unversioned.GroupVersion{}
}
return append([]unversioned.GroupVersion{}, groupMeta.GroupVersions...)
}
// Group returns the metadata of a group if the group is registered, otherwise
// an error is returned.
func (m *APIRegistrationManager) Group(group string) (*apimachinery.GroupMeta, error) {
groupMeta, found := m.groupMetaMap[group]
if !found {
return nil, fmt.Errorf("group %v has not been registered", group)
}
groupMetaCopy := *groupMeta
return &groupMetaCopy, nil
}
// IsRegistered takes a string and determines if it's one of the registered groups
func (m *APIRegistrationManager) IsRegistered(group string) bool {
_, found := m.groupMetaMap[group]
return found
}
// IsRegisteredVersion returns if a version is registered.
func (m *APIRegistrationManager) IsRegisteredVersion(v unversioned.GroupVersion) bool {
_, found := m.registeredVersions[v]
return found
}
// RegisteredGroupVersions returns all registered group versions.
func (m *APIRegistrationManager) RegisteredGroupVersions() []unversioned.GroupVersion {
ret := []unversioned.GroupVersion{}
for groupVersion := range m.registeredVersions {
ret = append(ret, groupVersion)
}
return ret
}
// IsThirdPartyAPIGroupVersion returns true if the api version is a user-registered group/version.
func (m *APIRegistrationManager) IsThirdPartyAPIGroupVersion(gv unversioned.GroupVersion) bool {
for ix := range m.thirdPartyGroupVersions {
if m.thirdPartyGroupVersions[ix] == gv {
return true
}
}
return false
}
// AddThirdPartyAPIGroupVersions sets the list of third party versions,
// registers them in the API machinery and enables them.
// Skips GroupVersions that are already registered.
// Returns the list of GroupVersions that were skipped.
func (m *APIRegistrationManager) AddThirdPartyAPIGroupVersions(gvs ...unversioned.GroupVersion) []unversioned.GroupVersion {
filteredGVs := []unversioned.GroupVersion{}
skippedGVs := []unversioned.GroupVersion{}
for ix := range gvs {
if !m.IsRegisteredVersion(gvs[ix]) {
filteredGVs = append(filteredGVs, gvs[ix])
} else {
glog.V(3).Infof("Skipping %s, because its already registered", gvs[ix].String())
skippedGVs = append(skippedGVs, gvs[ix])
}
}
if len(filteredGVs) == 0 {
return skippedGVs
}
m.RegisterVersions(filteredGVs)
m.EnableVersions(filteredGVs...)
m.thirdPartyGroupVersions = append(m.thirdPartyGroupVersions, filteredGVs...)
return skippedGVs
}
// TODO: This is an expedient function, because we don't check if a Group is
// supported throughout the code base. We will abandon this function and
// checking the error returned by the Group() function.
func (m *APIRegistrationManager) GroupOrDie(group string) *apimachinery.GroupMeta {
groupMeta, found := m.groupMetaMap[group]
if !found {
if group == "" {
panic("The legacy v1 API is not registered.")
} else {
panic(fmt.Sprintf("Group %s is not registered.", group))
}
}
groupMetaCopy := *groupMeta
return &groupMetaCopy
}
// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
// 1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR
// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
// kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
// all other groups alphabetical.
func (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper {
unionMapper := meta.MultiRESTMapper{}
unionedGroups := sets.NewString()
for enabledVersion := range m.enabledVersions {
if !unionedGroups.Has(enabledVersion.Group) {
unionedGroups.Insert(enabledVersion.Group)
groupMeta := m.groupMetaMap[enabledVersion.Group]
unionMapper = append(unionMapper, groupMeta.RESTMapper)
}
}
if len(versionPatterns) != 0 {
resourcePriority := []unversioned.GroupVersionResource{}
kindPriority := []unversioned.GroupVersionKind{}
for _, versionPriority := range versionPatterns {
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
}
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
if len(m.envRequestedVersions) != 0 {
resourcePriority := []unversioned.GroupVersionResource{}
kindPriority := []unversioned.GroupVersionKind{}
for _, versionPriority := range m.envRequestedVersions {
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
}
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
prioritizedGroups := []string{"", "extensions", "metrics"}
resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...)
prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
remainingGroups := sets.String{}
for enabledVersion := range m.enabledVersions {
if !prioritizedGroupsSet.Has(enabledVersion.Group) {
remainingGroups.Insert(enabledVersion.Group)
}
}
remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...)
resourcePriority = append(resourcePriority, remainingResourcePriority...)
kindPriority = append(kindPriority, remainingKindPriority...)
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
// then any non-preferred version of the group second.
func (m *APIRegistrationManager) prioritiesForGroups(groups ...string) ([]unversioned.GroupVersionResource, []unversioned.GroupVersionKind) {
resourcePriority := []unversioned.GroupVersionResource{}
kindPriority := []unversioned.GroupVersionKind{}
for _, group := range groups {
availableVersions := m.EnabledVersionsForGroup(group)
if len(availableVersions) > 0 {
resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
}
}
for _, group := range groups {
resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
kindPriority = append(kindPriority, unversioned.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
}
return resourcePriority, kindPriority
}
// AllPreferredGroupVersions returns the preferred versions of all registered
// groups in the form of "group1/version1,group2/version2,..."
func (m *APIRegistrationManager) AllPreferredGroupVersions() string {
if len(m.groupMetaMap) == 0 {
return ""
}
var defaults []string
for _, groupMeta := range m.groupMetaMap {
defaults = append(defaults, groupMeta.GroupVersion.String())
}
sort.Strings(defaults)
return strings.Join(defaults, ",")
}
// ValidateEnvRequestedVersions returns a list of versions that are requested in
// the KUBE_API_VERSIONS environment variable, but not enabled.
func (m *APIRegistrationManager) ValidateEnvRequestedVersions() []unversioned.GroupVersion {
var missingVersions []unversioned.GroupVersion
for _, v := range m.envRequestedVersions {
if _, found := m.enabledVersions[v]; !found {
missingVersions = append(missingVersions, v)
}
}
return missingVersions
}

52
vendor/k8s.io/client-go/1.4/pkg/apimachinery/types.go generated vendored Normal file
View file

@ -0,0 +1,52 @@
/*
Copyright 2016 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 apimachinery
import (
"k8s.io/client-go/1.4/pkg/api/meta"
"k8s.io/client-go/1.4/pkg/api/unversioned"
"k8s.io/client-go/1.4/pkg/runtime"
)
// GroupMeta stores the metadata of a group.
type GroupMeta struct {
// GroupVersion represents the preferred version of the group.
GroupVersion unversioned.GroupVersion
// GroupVersions is Group + all versions in that group.
GroupVersions []unversioned.GroupVersion
// Codec is the default codec for serializing output that should use
// the preferred version. Use this Codec when writing to
// disk, a data store that is not dynamically versioned, or in tests.
// This codec can decode any object that the schema is aware of.
Codec runtime.Codec
// SelfLinker can set or get the SelfLink field of all API types.
// TODO: when versioning changes, make this part of each API definition.
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
// to go through the InterfacesFor method below.
SelfLinker runtime.SelfLinker
// RESTMapper provides the default mapping between REST paths and the objects declared in api.Scheme and all known
// versions.
RESTMapper meta.RESTMapper
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
// or an error if the version is not known.
InterfacesFor func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error)
}

View file

@ -28,12 +28,12 @@ const GroupName = "autoscaling"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) unversioned.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

View file

@ -2575,7 +2575,7 @@ func (x codecSelfer1234) decSliceHorizontalPodAutoscaler(v *[]HorizontalPodAutos
yyrg220 := len(yyv220) > 0
yyv2220 := yyv220
yyrl220, yyrt220 = z.DecInferLen(yyl220, z.DecBasicHandle().MaxInitLen, 344)
yyrl220, yyrt220 = z.DecInferLen(yyl220, z.DecBasicHandle().MaxInitLen, 360)
if yyrt220 {
if yyrl220 <= cap(yyv220) {
yyv220 = yyv220[:yyrl220]

View file

@ -28,12 +28,12 @@ const GroupName = "batch"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) unversioned.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

View file

@ -4247,7 +4247,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) {
yyrg370 := len(yyv370) > 0
yyv2370 := yyv370
yyrl370, yyrt370 = z.DecInferLen(yyl370, z.DecBasicHandle().MaxInitLen, 768)
yyrl370, yyrt370 = z.DecInferLen(yyl370, z.DecBasicHandle().MaxInitLen, 800)
if yyrt370 {
if yyrl370 <= cap(yyv370) {
yyv370 = yyv370[:yyrl370]
@ -4479,7 +4479,7 @@ func (x codecSelfer1234) decSliceScheduledJob(v *[]ScheduledJob, d *codec1978.De
yyrg382 := len(yyv382) > 0
yyv2382 := yyv382
yyrl382, yyrt382 = z.DecInferLen(yyl382, z.DecBasicHandle().MaxInitLen, 1000)
yyrl382, yyrt382 = z.DecInferLen(yyl382, z.DecBasicHandle().MaxInitLen, 1048)
if yyrt382 {
if yyrl382 <= cap(yyv382) {
yyv382 = yyv382[:yyrl382]

View file

@ -0,0 +1,37 @@
/*
Copyright 2016 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 extensions
import (
"strings"
)
// SysctlsFromPodSecurityPolicyAnnotation parses an annotation value of the key
// SysctlsSecurityPolocyAnnotationKey into a slice of sysctls. An empty slice
// is returned if annotation is the empty string.
func SysctlsFromPodSecurityPolicyAnnotation(annotation string) ([]string, error) {
if len(annotation) == 0 {
return []string{}, nil
}
return strings.Split(annotation, ","), nil
}
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
func PodAnnotationsFromSysctls(sysctls []string) string {
return strings.Join(sysctls, ",")
}

View file

@ -30,12 +30,12 @@ const GroupName = "extensions"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) unversioned.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
@ -68,6 +68,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&Ingress{},
&IngressList{},
&api.ListOptions{},
&api.DeleteOptions{},
&ReplicaSet{},
&ReplicaSetList{},
&api.ExportOptions{},

View file

@ -35,6 +35,13 @@ import (
"k8s.io/client-go/1.4/pkg/util/intstr"
)
const (
// SysctlsPodSecurityPolicyAnnotationKey represents the key of a whitelist of
// allowed safe and unsafe sysctls in a pod spec. It's a comma-separated list of plain sysctl
// names or sysctl patterns (which end in *). The string "*" matches all sysctls.
SysctlsPodSecurityPolicyAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
)
// describes the attributes of a scale subresource
type ScaleSpec struct {
// desired number of instances for the scaled object.
@ -550,7 +557,7 @@ type HTTPIngressRuleValue struct {
// HTTPIngressPath associates a path regex with a backend. Incoming urls matching
// the path are forwarded to the backend.
type HTTPIngressPath struct {
// Path is a extended POSIX regex as defined by IEEE Std 1003.1,
// Path is an extended POSIX regex as defined by IEEE Std 1003.1,
// (i.e this follows the egrep/unix syntax, not the perl syntax)
// matched against the path of an incoming request. Currently it can
// contain characters disallowed from the conventional "path"
@ -622,6 +629,9 @@ type ReplicaSetStatus struct {
// The number of pods that have labels matching the labels of the pod template of the replicaset.
FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"`
// The number of ready replicas for this replica set.
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
// ObservedGeneration is the most recent generation observed by the controller.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}
@ -714,6 +724,8 @@ var (
FC FSType = "fc"
ConfigMap FSType = "configMap"
VsphereVolume FSType = "vsphereVolume"
Quobyte FSType = "quobyte"
AzureDisk FSType = "azureDisk"
All FSType = "*"
)

View file

@ -870,6 +870,7 @@ func DeepCopy_extensions_ReplicaSetStatus(in interface{}, out interface{}, c *co
out := out.(*ReplicaSetStatus)
out.Replicas = in.Replicas
out.FullyLabeledReplicas = in.FullyLabeledReplicas
out.ReadyReplicas = in.ReadyReplicas
out.ObservedGeneration = in.ObservedGeneration
return nil
}

View file

@ -36,6 +36,8 @@ type Info interface {
// This is a map[string][]string because it needs to be serializeable into
// a SubjectAccessReviewSpec.authorization.k8s.io for proper authorization
// delegation flows
// In order to faithfully round-trip through an impersonation flow, these keys
// MUST be lowercase.
GetExtra() map[string][]string
}

Some files were not shown because too many files have changed in this diff Show more