mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: update kubernetes to v1.25.0
update kubernetes to latest v1.25.0 release. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
f47839d73d
commit
e3bf375035
8
vendor/k8s.io/kubernetes/pkg/apis/apps/types.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/apis/apps/types.go
generated
vendored
@ -27,8 +27,9 @@ import (
|
||||
|
||||
// StatefulSet represents a set of pods with consistent identities.
|
||||
// Identities are defined as:
|
||||
// - Network: A single stable DNS and hostname.
|
||||
// - Storage: As many VolumeClaims as requested.
|
||||
// - Network: A single stable DNS and hostname.
|
||||
// - Storage: As many VolumeClaims as requested.
|
||||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
type StatefulSet struct {
|
||||
@ -206,7 +207,6 @@ type StatefulSetSpec struct {
|
||||
// Minimum number of seconds for which a newly created pod should be ready
|
||||
// without any of its container crashing for it to be considered available.
|
||||
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||
// This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.
|
||||
// +optional
|
||||
MinReadySeconds int32
|
||||
|
||||
@ -256,7 +256,6 @@ type StatefulSetStatus struct {
|
||||
Conditions []StatefulSetCondition
|
||||
|
||||
// Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset.
|
||||
// This is a beta field and requires enabling StatefulSetMinReadySeconds feature gate.
|
||||
// +optional
|
||||
AvailableReplicas int32
|
||||
}
|
||||
@ -627,7 +626,6 @@ type RollingUpdateDaemonSet struct {
|
||||
// daemonset on any given node can double if the readiness check fails, and
|
||||
// so resource intensive daemonsets should take into account that they may
|
||||
// cause evictions during disruption.
|
||||
// This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.
|
||||
// +optional
|
||||
MaxSurge intstr.IntOrString
|
||||
}
|
||||
|
18
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/helpers.go
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/helpers.go
generated
vendored
@ -21,16 +21,16 @@ package autoscaling
|
||||
// It should always be called when converting internal -> external versions, prior
|
||||
// to setting any of the custom annotations:
|
||||
//
|
||||
// annotations, copiedAnnotations := DropRoundTripHorizontalPodAutoscalerAnnotations(externalObj.Annotations)
|
||||
// externalObj.Annotations = annotations
|
||||
// annotations, copiedAnnotations := DropRoundTripHorizontalPodAutoscalerAnnotations(externalObj.Annotations)
|
||||
// externalObj.Annotations = annotations
|
||||
//
|
||||
// if internal.SomeField != nil {
|
||||
// if !copiedAnnotations {
|
||||
// externalObj.Annotations = DeepCopyStringMap(externalObj.Annotations)
|
||||
// copiedAnnotations = true
|
||||
// }
|
||||
// externalObj.Annotations[...] = json.Marshal(...)
|
||||
// }
|
||||
// if internal.SomeField != nil {
|
||||
// if !copiedAnnotations {
|
||||
// externalObj.Annotations = DeepCopyStringMap(externalObj.Annotations)
|
||||
// copiedAnnotations = true
|
||||
// }
|
||||
// externalObj.Annotations[...] = json.Marshal(...)
|
||||
// }
|
||||
func DropRoundTripHorizontalPodAutoscalerAnnotations(in map[string]string) (out map[string]string, copied bool) {
|
||||
_, hasMetricsSpecs := in[MetricSpecsAnnotation]
|
||||
_, hasBehaviorSpecs := in[BehaviorSpecsAnnotation]
|
||||
|
142
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
142
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
@ -110,6 +110,119 @@ const (
|
||||
IndexedCompletion CompletionMode = "Indexed"
|
||||
)
|
||||
|
||||
// PodFailurePolicyAction specifies how a Pod failure is handled.
|
||||
// +enum
|
||||
type PodFailurePolicyAction string
|
||||
|
||||
const (
|
||||
// This is an action which might be taken on a pod failure - mark the
|
||||
// pod's job as Failed and terminate all running pods.
|
||||
PodFailurePolicyActionFailJob PodFailurePolicyAction = "FailJob"
|
||||
|
||||
// This is an action which might be taken on a pod failure - the counter towards
|
||||
// .backoffLimit, represented by the job's .status.failed field, is not
|
||||
// incremented and a replacement pod is created.
|
||||
PodFailurePolicyActionIgnore PodFailurePolicyAction = "Ignore"
|
||||
|
||||
// This is an action which might be taken on a pod failure - the pod failure
|
||||
// is handled in the default way - the counter towards .backoffLimit,
|
||||
// represented by the job's .status.failed field, is incremented.
|
||||
PodFailurePolicyActionCount PodFailurePolicyAction = "Count"
|
||||
)
|
||||
|
||||
// +enum
|
||||
type PodFailurePolicyOnExitCodesOperator string
|
||||
|
||||
const (
|
||||
PodFailurePolicyOnExitCodesOpIn PodFailurePolicyOnExitCodesOperator = "In"
|
||||
PodFailurePolicyOnExitCodesOpNotIn PodFailurePolicyOnExitCodesOperator = "NotIn"
|
||||
)
|
||||
|
||||
// PodFailurePolicyOnExitCodesRequirement describes the requirement for handling
|
||||
// a failed pod based on its container exit codes. In particular, it lookups the
|
||||
// .state.terminated.exitCode for each app container and init container status,
|
||||
// represented by the .status.containerStatuses and .status.initContainerStatuses
|
||||
// fields in the Pod status, respectively. Containers completed with success
|
||||
// (exit code 0) are excluded from the requirement check.
|
||||
type PodFailurePolicyOnExitCodesRequirement struct {
|
||||
// Restricts the check for exit codes to the container with the
|
||||
// specified name. When null, the rule applies to all containers.
|
||||
// When specified, it should match one the container or initContainer
|
||||
// names in the pod template.
|
||||
// +optional
|
||||
ContainerName *string
|
||||
|
||||
// Represents the relationship between the container exit code(s) and the
|
||||
// specified values. Containers completed with success (exit code 0) are
|
||||
// excluded from the requirement check. Possible values are:
|
||||
// - In: the requirement is satisfied if at least one container exit code
|
||||
// (might be multiple if there are multiple containers not restricted
|
||||
// by the 'containerName' field) is in the set of specified values.
|
||||
// - NotIn: the requirement is satisfied if at least one container exit code
|
||||
// (might be multiple if there are multiple containers not restricted
|
||||
// by the 'containerName' field) is not in the set of specified values.
|
||||
// Additional values are considered to be added in the future. Clients should
|
||||
// react to an unknown operator by assuming the requirement is not satisfied.
|
||||
Operator PodFailurePolicyOnExitCodesOperator
|
||||
|
||||
// Specifies the set of values. Each returned container exit code (might be
|
||||
// multiple in case of multiple containers) is checked against this set of
|
||||
// values with respect to the operator. The list of values must be ordered
|
||||
// and must not contain duplicates. Value '0' cannot be used for the In operator.
|
||||
// At least one element is required. At most 255 elements are allowed.
|
||||
// +listType=set
|
||||
Values []int32
|
||||
}
|
||||
|
||||
// PodFailurePolicyOnPodConditionsPattern describes a pattern for matching
|
||||
// an actual pod condition type.
|
||||
type PodFailurePolicyOnPodConditionsPattern struct {
|
||||
// Specifies the required Pod condition type. To match a pod condition
|
||||
// it is required that specified type equals the pod condition type.
|
||||
Type api.PodConditionType
|
||||
// Specifies the required Pod condition status. To match a pod condition
|
||||
// it is required that the specified status equals the pod condition status.
|
||||
// Defaults to True.
|
||||
Status api.ConditionStatus
|
||||
}
|
||||
|
||||
// PodFailurePolicyRule describes how a pod failure is handled when the requirements are met.
|
||||
// One of OnExitCodes and onPodConditions, but not both, can be used in each rule.
|
||||
type PodFailurePolicyRule struct {
|
||||
// Specifies the action taken on a pod failure when the requirements are satisfied.
|
||||
// Possible values are:
|
||||
// - FailJob: indicates that the pod's job is marked as Failed and all
|
||||
// running pods are terminated.
|
||||
// - Ignore: indicates that the counter towards the .backoffLimit is not
|
||||
// incremented and a replacement pod is created.
|
||||
// - Count: indicates that the pod is handled in the default way - the
|
||||
// counter towards the .backoffLimit is incremented.
|
||||
// Additional values are considered to be added in the future. Clients should
|
||||
// react to an unknown action by skipping the rule.
|
||||
Action PodFailurePolicyAction
|
||||
|
||||
// Represents the requirement on the container exit codes.
|
||||
// +optional
|
||||
OnExitCodes *PodFailurePolicyOnExitCodesRequirement
|
||||
|
||||
// Represents the requirement on the pod conditions. The requirement is represented
|
||||
// as a list of pod condition patterns. The requirement is satisfied if at
|
||||
// least one pattern matches an actual pod condition. At most 20 elements are allowed.
|
||||
// +listType=atomic
|
||||
OnPodConditions []PodFailurePolicyOnPodConditionsPattern
|
||||
}
|
||||
|
||||
// PodFailurePolicy describes how failed pods influence the backoffLimit.
|
||||
type PodFailurePolicy struct {
|
||||
// A list of pod failure policy rules. The rules are evaluated in order.
|
||||
// Once a rule matches a Pod failure, the remaining of the rules are ignored.
|
||||
// When no rule matches the Pod failure, the default handling applies - the
|
||||
// counter of pod failures is incremented and it is checked against
|
||||
// the backoffLimit. At most 20 elements are allowed.
|
||||
// +listType=atomic
|
||||
Rules []PodFailurePolicyRule
|
||||
}
|
||||
|
||||
// JobSpec describes how the job execution will look like.
|
||||
type JobSpec struct {
|
||||
|
||||
@ -128,6 +241,19 @@ type JobSpec struct {
|
||||
// +optional
|
||||
Completions *int32
|
||||
|
||||
// Specifies the policy of handling failed pods. In particular, it allows to
|
||||
// specify the set of actions and conditions which need to be
|
||||
// satisfied to take the associated action.
|
||||
// If empty, the default behaviour applies - the counter of failed pods,
|
||||
// represented by the jobs's .status.failed field, is incremented and it is
|
||||
// checked against the backoffLimit. This field cannot be used in combination
|
||||
// with .spec.podTemplate.spec.restartPolicy=OnFailure.
|
||||
//
|
||||
// This field is alpha-level. To use this field, you must enable the
|
||||
// `JobPodFailurePolicy` feature gate (disabled by default).
|
||||
// +optional
|
||||
PodFailurePolicy *PodFailurePolicy
|
||||
|
||||
// Specifies the duration in seconds relative to the startTime that the job
|
||||
// may be continuously active before the system tries to terminate it; value
|
||||
// must be positive integer. If a Job is suspended (at creation or through an
|
||||
@ -313,6 +439,9 @@ const (
|
||||
JobComplete JobConditionType = "Complete"
|
||||
// JobFailed means the job has failed its execution.
|
||||
JobFailed JobConditionType = "Failed"
|
||||
// FailureTarget means the job is about to fail its execution.
|
||||
// The constant is to be renamed once the name is accepted within the KEP-3329.
|
||||
AlphaNoCompatGuaranteeJobFailureTarget JobConditionType = "FailureTarget"
|
||||
)
|
||||
|
||||
// JobCondition describes current state of a job.
|
||||
@ -376,9 +505,16 @@ type CronJobSpec struct {
|
||||
// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
|
||||
Schedule string
|
||||
|
||||
// The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
|
||||
// If not specified, this will rely on the time zone of the kube-controller-manager process.
|
||||
// ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate.
|
||||
// The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
|
||||
// If not specified, this will default to the time zone of the kube-controller-manager process.
|
||||
// The set of valid time zone names and the time zone offset is loaded from the system-wide time zone
|
||||
// database by the API server during CronJob validation and the controller manager during execution.
|
||||
// If no system-wide time zone database can be found a bundled version of the database is used instead.
|
||||
// If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host
|
||||
// configuration, the controller will stop creating new new Jobs and will create a system event with the
|
||||
// reason UnknownTimeZone.
|
||||
// More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones
|
||||
// This is beta field and must be enabled via the `CronJobTimeZone` feature gate.
|
||||
// +optional
|
||||
TimeZone *string
|
||||
|
||||
|
96
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
96
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
@ -252,6 +252,11 @@ func (in *JobSpec) DeepCopyInto(out *JobSpec) {
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.PodFailurePolicy != nil {
|
||||
in, out := &in.PodFailurePolicy, &out.PodFailurePolicy
|
||||
*out = new(PodFailurePolicy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ActiveDeadlineSeconds != nil {
|
||||
in, out := &in.ActiveDeadlineSeconds, &out.ActiveDeadlineSeconds
|
||||
*out = new(int64)
|
||||
@ -387,6 +392,97 @@ func (in *JobTemplateSpec) DeepCopy() *JobTemplateSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodFailurePolicy) DeepCopyInto(out *PodFailurePolicy) {
|
||||
*out = *in
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]PodFailurePolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicy.
|
||||
func (in *PodFailurePolicy) DeepCopy() *PodFailurePolicy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodFailurePolicy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodFailurePolicyOnExitCodesRequirement) DeepCopyInto(out *PodFailurePolicyOnExitCodesRequirement) {
|
||||
*out = *in
|
||||
if in.ContainerName != nil {
|
||||
in, out := &in.ContainerName, &out.ContainerName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]int32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicyOnExitCodesRequirement.
|
||||
func (in *PodFailurePolicyOnExitCodesRequirement) DeepCopy() *PodFailurePolicyOnExitCodesRequirement {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodFailurePolicyOnExitCodesRequirement)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodFailurePolicyOnPodConditionsPattern) DeepCopyInto(out *PodFailurePolicyOnPodConditionsPattern) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicyOnPodConditionsPattern.
|
||||
func (in *PodFailurePolicyOnPodConditionsPattern) DeepCopy() *PodFailurePolicyOnPodConditionsPattern {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodFailurePolicyOnPodConditionsPattern)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodFailurePolicyRule) DeepCopyInto(out *PodFailurePolicyRule) {
|
||||
*out = *in
|
||||
if in.OnExitCodes != nil {
|
||||
in, out := &in.OnExitCodes, &out.OnExitCodes
|
||||
*out = new(PodFailurePolicyOnExitCodesRequirement)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.OnPodConditions != nil {
|
||||
in, out := &in.OnPodConditions, &out.OnPodConditions
|
||||
*out = make([]PodFailurePolicyOnPodConditionsPattern, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicyRule.
|
||||
func (in *PodFailurePolicyRule) DeepCopy() *PodFailurePolicyRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodFailurePolicyRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UncountedTerminatedPods) DeepCopyInto(out *UncountedTerminatedPods) {
|
||||
*out = *in
|
||||
|
67
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
67
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
@ -27,7 +27,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
@ -361,72 +360,6 @@ func ContainsAccessMode(modes []core.PersistentVolumeAccessMode, mode core.Persi
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement core type into a struct that implements
|
||||
// labels.Selector.
|
||||
func NodeSelectorRequirementsAsSelector(nsm []core.NodeSelectorRequirement) (labels.Selector, error) {
|
||||
if len(nsm) == 0 {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
selector := labels.NewSelector()
|
||||
for _, expr := range nsm {
|
||||
var op selection.Operator
|
||||
switch expr.Operator {
|
||||
case core.NodeSelectorOpIn:
|
||||
op = selection.In
|
||||
case core.NodeSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case core.NodeSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case core.NodeSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
case core.NodeSelectorOpGt:
|
||||
op = selection.GreaterThan
|
||||
case core.NodeSelectorOpLt:
|
||||
op = selection.LessThan
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
||||
}
|
||||
r, err := labels.NewRequirement(expr.Key, op, expr.Values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// NodeSelectorRequirementsAsFieldSelector converts the []NodeSelectorRequirement core type into a struct that implements
|
||||
// fields.Selector.
|
||||
func NodeSelectorRequirementsAsFieldSelector(nsm []core.NodeSelectorRequirement) (fields.Selector, error) {
|
||||
if len(nsm) == 0 {
|
||||
return fields.Nothing(), nil
|
||||
}
|
||||
|
||||
selectors := []fields.Selector{}
|
||||
for _, expr := range nsm {
|
||||
switch expr.Operator {
|
||||
case core.NodeSelectorOpIn:
|
||||
if len(expr.Values) != 1 {
|
||||
return nil, fmt.Errorf("unexpected number of value (%d) for node field selector operator %q",
|
||||
len(expr.Values), expr.Operator)
|
||||
}
|
||||
selectors = append(selectors, fields.OneTermEqualSelector(expr.Key, expr.Values[0]))
|
||||
|
||||
case core.NodeSelectorOpNotIn:
|
||||
if len(expr.Values) != 1 {
|
||||
return nil, fmt.Errorf("unexpected number of value (%d) for node field selector operator %q",
|
||||
len(expr.Values), expr.Operator)
|
||||
}
|
||||
selectors = append(selectors, fields.OneTermNotEqualSelector(expr.Key, expr.Values[0]))
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid node field selector operator", expr.Operator)
|
||||
}
|
||||
}
|
||||
|
||||
return fields.AndSelectors(selectors...), nil
|
||||
}
|
||||
|
||||
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
||||
// and converts it to the []Toleration type in core.
|
||||
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]core.Toleration, error) {
|
||||
|
12
vendor/k8s.io/kubernetes/pkg/apis/core/pods/helpers.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/apis/core/pods/helpers.go
generated
vendored
@ -20,9 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/fieldpath"
|
||||
)
|
||||
|
||||
@ -47,12 +45,10 @@ func VisitContainersWithPath(podSpec *api.PodSpec, specPath *field.Path, visitor
|
||||
return false
|
||||
}
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
fldPath = specPath.Child("ephemeralContainers")
|
||||
for i := range podSpec.EphemeralContainers {
|
||||
if !visitor((*api.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), fldPath.Index(i)) {
|
||||
return false
|
||||
}
|
||||
fldPath = specPath.Child("ephemeralContainers")
|
||||
for i := range podSpec.EphemeralContainers {
|
||||
if !visitor((*api.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), fldPath.Index(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
189
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
189
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
@ -154,7 +154,7 @@ type VolumeSource struct {
|
||||
// StorageOS represents a StorageOS volume that is attached to the kubelet's host machine and mounted into the pod
|
||||
// +optional
|
||||
StorageOS *StorageOSVolumeSource
|
||||
// CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).
|
||||
// CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.
|
||||
// +optional
|
||||
CSI *CSIVolumeSource
|
||||
// Ephemeral represents a volume that is handled by a cluster storage driver.
|
||||
@ -1716,11 +1716,20 @@ type CSIPersistentVolumeSource struct {
|
||||
// ControllerExpandSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// ControllerExpandVolume call.
|
||||
// This is an alpha field and requires enabling ExpandCSIVolumes feature gate.
|
||||
// This is an beta field and requires enabling ExpandCSIVolumes feature gate.
|
||||
// This field is optional, and may be empty if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
ControllerExpandSecretRef *SecretReference
|
||||
|
||||
// NodeExpandSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// NodeExpandVolume call.
|
||||
// This is an alpha field and requires enabling CSINodeExpandSecret feature gate.
|
||||
// This field is optional, may be omitted if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
NodeExpandSecretRef *SecretReference
|
||||
}
|
||||
|
||||
// CSIVolumeSource represents a source location of a volume to mount, managed by an external CSI driver
|
||||
@ -2421,6 +2430,10 @@ const (
|
||||
PodReasonUnschedulable = "Unschedulable"
|
||||
// ContainersReady indicates whether all containers in the pod are ready.
|
||||
ContainersReady PodConditionType = "ContainersReady"
|
||||
// AlphaNoCompatGuaranteeDisruptionTarget indicates the pod is about to be deleted due to a
|
||||
// disruption (such as preemption, eviction API or garbage-collection).
|
||||
// The constant is to be renamed once the name is accepted within the KEP-3329.
|
||||
AlphaNoCompatGuaranteeDisruptionTarget PodConditionType = "DisruptionTarget"
|
||||
)
|
||||
|
||||
// PodCondition represents pod's condition
|
||||
@ -2820,7 +2833,6 @@ type PodSpec struct {
|
||||
// pod to perform user-initiated actions such as debugging. This list cannot be specified when
|
||||
// creating a pod, and it cannot be modified by updating the pod spec. In order to add an
|
||||
// ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.
|
||||
// This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.
|
||||
// +optional
|
||||
EphemeralContainers []EphemeralContainer
|
||||
// +optional
|
||||
@ -2964,6 +2976,7 @@ type PodSpec struct {
|
||||
// If the OS field is set to windows, following fields must be unset:
|
||||
// - spec.hostPID
|
||||
// - spec.hostIPC
|
||||
// - spec.hostUsers
|
||||
// - spec.securityContext.seLinuxOptions
|
||||
// - spec.securityContext.seccompProfile
|
||||
// - spec.securityContext.fsGroup
|
||||
@ -2983,7 +2996,6 @@ type PodSpec struct {
|
||||
// - spec.containers[*].securityContext.runAsUser
|
||||
// - spec.containers[*].securityContext.runAsGroup
|
||||
// +optional
|
||||
// This is a beta field and requires the IdentifyPodOS feature
|
||||
OS *PodOS
|
||||
}
|
||||
|
||||
@ -3067,6 +3079,18 @@ type PodSecurityContext struct {
|
||||
// +k8s:conversion-gen=false
|
||||
// +optional
|
||||
ShareProcessNamespace *bool
|
||||
// Use the host's user namespace.
|
||||
// Optional: Default to true.
|
||||
// If set to true or not present, the pod will be run in the host user namespace, useful
|
||||
// for when the pod needs a feature only available to the host user namespace, such as
|
||||
// loading a kernel module with CAP_SYS_MODULE.
|
||||
// When set to false, a new user namespace is created for the pod. Setting false is useful
|
||||
// for mitigating container breakout vulnerabilities even allowing users to run their
|
||||
// containers as root without actually having root privileges on the host.
|
||||
// Note that this field cannot be set when spec.os.name is windows.
|
||||
// +k8s:conversion-gen=false
|
||||
// +optional
|
||||
HostUsers *bool
|
||||
// The SELinux context to be applied to all containers.
|
||||
// If unspecified, the container runtime will allocate a random SELinux context for each
|
||||
// container. May also be set in SecurityContext. If set in
|
||||
@ -3213,8 +3237,9 @@ type PodDNSConfigOption struct {
|
||||
|
||||
// PodIP represents the IP address of a pod.
|
||||
// IP address information. Each entry includes:
|
||||
// IP: An IP address allocated to the pod. Routable at least within
|
||||
// the cluster.
|
||||
//
|
||||
// IP: An IP address allocated to the pod. Routable at least within
|
||||
// the cluster.
|
||||
type PodIP struct {
|
||||
IP string
|
||||
}
|
||||
@ -3317,8 +3342,6 @@ var _ = Container(EphemeralContainerCommon{})
|
||||
//
|
||||
// To add an ephemeral container, use the ephemeralcontainers subresource of an existing
|
||||
// Pod. Ephemeral containers may not be removed or restarted.
|
||||
//
|
||||
// This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.
|
||||
type EphemeralContainer struct {
|
||||
// Ephemeral containers have all of the fields of Container, plus additional fields
|
||||
// specific to ephemeral containers. Fields in common with Container are in the
|
||||
@ -3381,7 +3404,6 @@ type PodStatus struct {
|
||||
ContainerStatuses []ContainerStatus
|
||||
|
||||
// Status for any ephemeral containers that have run in this pod.
|
||||
// This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.
|
||||
// +optional
|
||||
EphemeralContainerStatuses []ContainerStatus
|
||||
}
|
||||
@ -3641,27 +3663,33 @@ const (
|
||||
ServiceTypeExternalName ServiceType = "ExternalName"
|
||||
)
|
||||
|
||||
// ServiceInternalTrafficPolicyType describes the type of traffic routing for
|
||||
// internal traffic
|
||||
// ServiceInternalTrafficPolicyType describes the endpoint-selection policy for
|
||||
// traffic sent to the ClusterIP.
|
||||
type ServiceInternalTrafficPolicyType string
|
||||
|
||||
const (
|
||||
// ServiceInternalTrafficPolicyCluster routes traffic to all endpoints
|
||||
// ServiceInternalTrafficPolicyCluster routes traffic to all endpoints.
|
||||
ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicyType = "Cluster"
|
||||
|
||||
// ServiceInternalTrafficPolicyLocal only routes to node-local
|
||||
// endpoints, otherwise drops the traffic
|
||||
// ServiceInternalTrafficPolicyLocal routes traffic only to endpoints on the same
|
||||
// node as the traffic was received on (dropping the traffic if there are no
|
||||
// local endpoints).
|
||||
ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicyType = "Local"
|
||||
)
|
||||
|
||||
// ServiceExternalTrafficPolicyType string
|
||||
// ServiceExternalTrafficPolicyType describes the endpoint-selection policy for
|
||||
// traffic to external service entrypoints (NodePorts, ExternalIPs, and
|
||||
// LoadBalancer IPs).
|
||||
type ServiceExternalTrafficPolicyType string
|
||||
|
||||
const (
|
||||
// ServiceExternalTrafficPolicyTypeLocal specifies node-local endpoints behavior.
|
||||
ServiceExternalTrafficPolicyTypeLocal ServiceExternalTrafficPolicyType = "Local"
|
||||
// ServiceExternalTrafficPolicyTypeCluster specifies cluster-wide (legacy) behavior.
|
||||
// ServiceExternalTrafficPolicyTypeCluster routes traffic to all endpoints.
|
||||
ServiceExternalTrafficPolicyTypeCluster ServiceExternalTrafficPolicyType = "Cluster"
|
||||
|
||||
// ServiceExternalTrafficPolicyTypeLocal preserves the source IP of the traffic by
|
||||
// routing only to endpoints on the same node as the traffic was received on
|
||||
// (dropping the traffic if there are no local endpoints).
|
||||
ServiceExternalTrafficPolicyTypeLocal ServiceExternalTrafficPolicyType = "Local"
|
||||
)
|
||||
|
||||
// These are the valid conditions of a service.
|
||||
@ -3721,27 +3749,27 @@ const (
|
||||
IPv6Protocol IPFamily = "IPv6"
|
||||
)
|
||||
|
||||
// IPFamilyPolicyType represents the dual-stack-ness requested or required by a Service
|
||||
type IPFamilyPolicyType string
|
||||
// IPFamilyPolicy represents the dual-stack-ness requested or required by a Service
|
||||
type IPFamilyPolicy string
|
||||
|
||||
const (
|
||||
// IPFamilyPolicySingleStack indicates that this service is required to have a single IPFamily.
|
||||
// The IPFamily assigned is based on the default IPFamily used by the cluster
|
||||
// or as identified by service.spec.ipFamilies field
|
||||
IPFamilyPolicySingleStack IPFamilyPolicyType = "SingleStack"
|
||||
IPFamilyPolicySingleStack IPFamilyPolicy = "SingleStack"
|
||||
// IPFamilyPolicyPreferDualStack indicates that this service prefers dual-stack when
|
||||
// the cluster is configured for dual-stack. If the cluster is not configured
|
||||
// for dual-stack the service will be assigned a single IPFamily. If the IPFamily is not
|
||||
// set in service.spec.ipFamilies then the service will be assigned the default IPFamily
|
||||
// configured on the cluster
|
||||
IPFamilyPolicyPreferDualStack IPFamilyPolicyType = "PreferDualStack"
|
||||
IPFamilyPolicyPreferDualStack IPFamilyPolicy = "PreferDualStack"
|
||||
// IPFamilyPolicyRequireDualStack indicates that this service requires dual-stack. Using
|
||||
// IPFamilyPolicyRequireDualStack on a single stack cluster will result in validation errors. The
|
||||
// IPFamilies (and their order) assigned to this service is based on service.spec.ipFamilies. If
|
||||
// service.spec.ipFamilies was not provided then it will be assigned according to how they are
|
||||
// configured on the cluster. If service.spec.ipFamilies has only one entry then the alternative
|
||||
// IPFamily will be added by apiserver
|
||||
IPFamilyPolicyRequireDualStack IPFamilyPolicyType = "RequireDualStack"
|
||||
IPFamilyPolicyRequireDualStack IPFamilyPolicy = "RequireDualStack"
|
||||
)
|
||||
|
||||
// ServiceSpec describes the attributes that a user creates on a service
|
||||
@ -3814,7 +3842,7 @@ type ServiceSpec struct {
|
||||
// to this service can be controlled by service.spec.ipFamilies and service.spec.clusterIPs
|
||||
// respectively.
|
||||
// +optional
|
||||
IPFamilyPolicy *IPFamilyPolicyType
|
||||
IPFamilyPolicy *IPFamilyPolicy
|
||||
|
||||
// ExternalName is the external reference that kubedns or equivalent will
|
||||
// return as a CNAME record for this service. No proxying will be involved.
|
||||
@ -3853,12 +3881,19 @@ type ServiceSpec struct {
|
||||
// +optional
|
||||
LoadBalancerSourceRanges []string
|
||||
|
||||
// externalTrafficPolicy denotes if this Service desires to route external
|
||||
// traffic to node-local or cluster-wide endpoints. "Local" preserves the
|
||||
// client source IP and avoids a second hop for LoadBalancer and Nodeport
|
||||
// type services, but risks potentially imbalanced traffic spreading.
|
||||
// "Cluster" obscures the client source IP and may cause a second hop to
|
||||
// another node, but should have good overall load-spreading.
|
||||
// externalTrafficPolicy describes how nodes distribute service traffic they
|
||||
// receive on one of the Service's "externally-facing" addresses (NodePorts,
|
||||
// ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure
|
||||
// the service in a way that assumes that external load balancers will take care
|
||||
// of balancing the service traffic between nodes, and so each node will deliver
|
||||
// traffic only to the node-local endpoints of the service, without masquerading
|
||||
// the client source IP. (Traffic mistakenly sent to a node with no endpoints will
|
||||
// be dropped.) The default value, "Cluster", uses the standard behavior of
|
||||
// routing to all endpoints evenly (possibly modified by topology and other
|
||||
// features). Note that traffic sent to an External IP or LoadBalancer IP from
|
||||
// within the cluster will always get "Cluster" semantics, but clients sending to
|
||||
// a NodePort from within the cluster may need to take traffic policy into account
|
||||
// when picking a node.
|
||||
// +optional
|
||||
ExternalTrafficPolicy ServiceExternalTrafficPolicyType
|
||||
|
||||
@ -3905,12 +3940,12 @@ type ServiceSpec struct {
|
||||
// +optional
|
||||
LoadBalancerClass *string
|
||||
|
||||
// InternalTrafficPolicy specifies if the cluster internal traffic
|
||||
// should be routed to all endpoints or node-local endpoints only.
|
||||
// "Cluster" routes internal traffic to a Service to all endpoints.
|
||||
// "Local" routes traffic to node-local endpoints only, traffic is
|
||||
// dropped if no node-local endpoints are ready.
|
||||
// The default value is "Cluster".
|
||||
// InternalTrafficPolicy describes how nodes distribute service traffic they
|
||||
// receive on the ClusterIP. If set to "Local", the proxy will assume that pods
|
||||
// only want to talk to endpoints of the service on the same node as the pod,
|
||||
// dropping the traffic if there are no local endpoints. The default value,
|
||||
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
||||
// (possibly modified by topology and other features).
|
||||
// +featureGate=ServiceInternalTrafficPolicy
|
||||
// +optional
|
||||
InternalTrafficPolicy *ServiceInternalTrafficPolicyType
|
||||
@ -4014,17 +4049,18 @@ type ServiceAccountList struct {
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Endpoints is a collection of endpoints that implement the actual service. Example:
|
||||
// Name: "mysvc",
|
||||
// Subsets: [
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
|
||||
// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
|
||||
// },
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.3.3"}],
|
||||
// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
|
||||
// },
|
||||
// ]
|
||||
//
|
||||
// Name: "mysvc",
|
||||
// Subsets: [
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
|
||||
// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
|
||||
// },
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.3.3"}],
|
||||
// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
|
||||
// },
|
||||
// ]
|
||||
type Endpoints struct {
|
||||
metav1.TypeMeta
|
||||
// +optional
|
||||
@ -4037,13 +4073,16 @@ type Endpoints struct {
|
||||
// EndpointSubset is a group of addresses with a common set of ports. The
|
||||
// expanded set of endpoints is the Cartesian product of Addresses x Ports.
|
||||
// For example, given:
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
|
||||
// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
|
||||
// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
|
||||
// }
|
||||
//
|
||||
// The resulting set of endpoints can be viewed as:
|
||||
// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],
|
||||
// b: [ 10.10.1.1:309, 10.10.2.2:309 ]
|
||||
//
|
||||
// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],
|
||||
// b: [ 10.10.1.1:309, 10.10.2.2:309 ]
|
||||
type EndpointSubset struct {
|
||||
Addresses []EndpointAddress
|
||||
NotReadyAddresses []EndpointAddress
|
||||
@ -5594,6 +5633,17 @@ const (
|
||||
ScheduleAnyway UnsatisfiableConstraintAction = "ScheduleAnyway"
|
||||
)
|
||||
|
||||
// NodeInclusionPolicy defines the type of node inclusion policy
|
||||
// +enum
|
||||
type NodeInclusionPolicy string
|
||||
|
||||
const (
|
||||
// NodeInclusionPolicyIgnore means ignore this scheduling directive when calculating pod topology spread skew.
|
||||
NodeInclusionPolicyIgnore NodeInclusionPolicy = "Ignore"
|
||||
// NodeInclusionPolicyHonor means use this scheduling directive when calculating pod topology spread skew.
|
||||
NodeInclusionPolicyHonor NodeInclusionPolicy = "Honor"
|
||||
)
|
||||
|
||||
// TopologySpreadConstraint specifies how to spread matching pods among the given topology.
|
||||
type TopologySpreadConstraint struct {
|
||||
// MaxSkew describes the degree to which pods may be unevenly distributed.
|
||||
@ -5622,7 +5672,8 @@ type TopologySpreadConstraint struct {
|
||||
// We consider each <key, value> as a "bucket", and try to put balanced number
|
||||
// of pods into each bucket.
|
||||
// We define a domain as a particular instance of a topology.
|
||||
// Also, we define an eligible domain as a domain whose nodes match the node selector.
|
||||
// Also, we define an eligible domain as a domain whose nodes meet the requirements of
|
||||
// nodeAffinityPolicy and nodeTaintsPolicy.
|
||||
// e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology.
|
||||
// And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology.
|
||||
// It's a required field.
|
||||
@ -5677,9 +5728,37 @@ type TopologySpreadConstraint struct {
|
||||
// because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,
|
||||
// it will violate MaxSkew.
|
||||
//
|
||||
// This is an alpha field and requires enabling MinDomainsInPodTopologySpread feature gate.
|
||||
// This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default).
|
||||
// +optional
|
||||
MinDomains *int32
|
||||
// NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector
|
||||
// when calculating pod topology spread skew. Options are:
|
||||
// - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.
|
||||
// - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
|
||||
//
|
||||
// If this value is nil, the behavior is equivalent to the Honor policy.
|
||||
// This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
|
||||
// +optional
|
||||
NodeAffinityPolicy *NodeInclusionPolicy
|
||||
// NodeTaintsPolicy indicates how we will treat node taints when calculating
|
||||
// pod topology spread skew. Options are:
|
||||
// - Honor: nodes without taints, along with tainted nodes for which the incoming pod
|
||||
// has a toleration, are included.
|
||||
// - Ignore: node taints are ignored. All nodes are included.
|
||||
//
|
||||
// If this value is nil, the behavior is equivalent to the Ignore policy.
|
||||
// This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
|
||||
// +optional
|
||||
NodeTaintsPolicy *NodeInclusionPolicy
|
||||
// MatchLabelKeys is a set of pod label keys to select the pods over which
|
||||
// spreading will be calculated. The keys are used to lookup values from the
|
||||
// incoming pod labels, those key-value labels are ANDed with labelSelector
|
||||
// to select the group of existing pods over which spreading will be calculated
|
||||
// for the incoming pod. Keys that don't exist in the incoming pod labels will
|
||||
// be ignored. A null or empty list means only match against labelSelector.
|
||||
// +listType=atomic
|
||||
// +optional
|
||||
MatchLabelKeys []string
|
||||
}
|
||||
|
||||
// These are the built-in errors for PortStatus.
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go
generated
vendored
@ -303,6 +303,7 @@ func Convert_core_PodSpec_To_v1_PodSpec(in *core.PodSpec, out *v1.PodSpec, s con
|
||||
out.HostNetwork = in.SecurityContext.HostNetwork
|
||||
out.HostIPC = in.SecurityContext.HostIPC
|
||||
out.ShareProcessNamespace = in.SecurityContext.ShareProcessNamespace
|
||||
out.HostUsers = in.SecurityContext.HostUsers
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -358,6 +359,7 @@ func Convert_v1_PodSpec_To_core_PodSpec(in *v1.PodSpec, out *core.PodSpec, s con
|
||||
out.SecurityContext.HostPID = in.HostPID
|
||||
out.SecurityContext.HostIPC = in.HostIPC
|
||||
out.SecurityContext.ShareProcessNamespace = in.ShareProcessNamespace
|
||||
out.SecurityContext.HostUsers = in.HostUsers
|
||||
|
||||
return nil
|
||||
}
|
||||
|
59
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
59
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
@ -370,3 +370,62 @@ func ScopedResourceSelectorRequirementsAsSelector(ssr v1.ScopedResourceSelectorR
|
||||
selector = selector.Add(*r)
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// nodeSelectorRequirementsAsLabelRequirements converts the NodeSelectorRequirement
|
||||
// type to a labels.Requirement type.
|
||||
func nodeSelectorRequirementsAsLabelRequirements(nsr v1.NodeSelectorRequirement) (*labels.Requirement, error) {
|
||||
var op selection.Operator
|
||||
switch nsr.Operator {
|
||||
case v1.NodeSelectorOpIn:
|
||||
op = selection.In
|
||||
case v1.NodeSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case v1.NodeSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case v1.NodeSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
case v1.NodeSelectorOpGt:
|
||||
op = selection.GreaterThan
|
||||
case v1.NodeSelectorOpLt:
|
||||
op = selection.LessThan
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid node selector operator", nsr.Operator)
|
||||
}
|
||||
return labels.NewRequirement(nsr.Key, op, nsr.Values)
|
||||
}
|
||||
|
||||
// NodeSelectorAsSelector converts the NodeSelector api type into a struct that
|
||||
// implements labels.Selector
|
||||
// Note: This function should be kept in sync with the selector methods in
|
||||
// pkg/labels/selector.go
|
||||
func NodeSelectorAsSelector(ns *v1.NodeSelector) (labels.Selector, error) {
|
||||
if ns == nil {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
if len(ns.NodeSelectorTerms) == 0 {
|
||||
return labels.Everything(), nil
|
||||
}
|
||||
var requirements []labels.Requirement
|
||||
|
||||
for _, nsTerm := range ns.NodeSelectorTerms {
|
||||
for _, expr := range nsTerm.MatchExpressions {
|
||||
req, err := nodeSelectorRequirementsAsLabelRequirements(expr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requirements = append(requirements, *req)
|
||||
}
|
||||
|
||||
for _, field := range nsTerm.MatchFields {
|
||||
req, err := nodeSelectorRequirementsAsLabelRequirements(field)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requirements = append(requirements, *req)
|
||||
}
|
||||
}
|
||||
|
||||
selector := labels.NewSelector()
|
||||
selector = selector.Add(requirements...)
|
||||
return selector, nil
|
||||
}
|
||||
|
14
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
14
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
@ -2423,6 +2423,7 @@ func autoConvert_v1_CSIPersistentVolumeSource_To_core_CSIPersistentVolumeSource(
|
||||
out.NodeStageSecretRef = (*core.SecretReference)(unsafe.Pointer(in.NodeStageSecretRef))
|
||||
out.NodePublishSecretRef = (*core.SecretReference)(unsafe.Pointer(in.NodePublishSecretRef))
|
||||
out.ControllerExpandSecretRef = (*core.SecretReference)(unsafe.Pointer(in.ControllerExpandSecretRef))
|
||||
out.NodeExpandSecretRef = (*core.SecretReference)(unsafe.Pointer(in.NodeExpandSecretRef))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -2441,6 +2442,7 @@ func autoConvert_core_CSIPersistentVolumeSource_To_v1_CSIPersistentVolumeSource(
|
||||
out.NodeStageSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.NodeStageSecretRef))
|
||||
out.NodePublishSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.NodePublishSecretRef))
|
||||
out.ControllerExpandSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.ControllerExpandSecretRef))
|
||||
out.NodeExpandSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.NodeExpandSecretRef))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6091,6 +6093,7 @@ func autoConvert_core_PodSecurityContext_To_v1_PodSecurityContext(in *core.PodSe
|
||||
// INFO: in.HostPID opted out of conversion generation
|
||||
// INFO: in.HostIPC opted out of conversion generation
|
||||
// INFO: in.ShareProcessNamespace opted out of conversion generation
|
||||
// INFO: in.HostUsers opted out of conversion generation
|
||||
out.SELinuxOptions = (*v1.SELinuxOptions)(unsafe.Pointer(in.SELinuxOptions))
|
||||
out.WindowsOptions = (*v1.WindowsSecurityContextOptions)(unsafe.Pointer(in.WindowsOptions))
|
||||
out.RunAsUser = (*int64)(unsafe.Pointer(in.RunAsUser))
|
||||
@ -6184,6 +6187,7 @@ func autoConvert_v1_PodSpec_To_core_PodSpec(in *v1.PodSpec, out *core.PodSpec, s
|
||||
out.TopologySpreadConstraints = *(*[]core.TopologySpreadConstraint)(unsafe.Pointer(&in.TopologySpreadConstraints))
|
||||
out.SetHostnameAsFQDN = (*bool)(unsafe.Pointer(in.SetHostnameAsFQDN))
|
||||
out.OS = (*core.PodOS)(unsafe.Pointer(in.OS))
|
||||
// INFO: in.HostUsers opted out of conversion generation
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -7707,7 +7711,7 @@ func autoConvert_v1_ServiceSpec_To_core_ServiceSpec(in *v1.ServiceSpec, out *cor
|
||||
out.PublishNotReadyAddresses = in.PublishNotReadyAddresses
|
||||
out.SessionAffinityConfig = (*core.SessionAffinityConfig)(unsafe.Pointer(in.SessionAffinityConfig))
|
||||
out.IPFamilies = *(*[]core.IPFamily)(unsafe.Pointer(&in.IPFamilies))
|
||||
out.IPFamilyPolicy = (*core.IPFamilyPolicyType)(unsafe.Pointer(in.IPFamilyPolicy))
|
||||
out.IPFamilyPolicy = (*core.IPFamilyPolicy)(unsafe.Pointer(in.IPFamilyPolicy))
|
||||
out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts))
|
||||
out.LoadBalancerClass = (*string)(unsafe.Pointer(in.LoadBalancerClass))
|
||||
out.InternalTrafficPolicy = (*core.ServiceInternalTrafficPolicyType)(unsafe.Pointer(in.InternalTrafficPolicy))
|
||||
@ -7726,7 +7730,7 @@ func autoConvert_core_ServiceSpec_To_v1_ServiceSpec(in *core.ServiceSpec, out *v
|
||||
out.ClusterIP = in.ClusterIP
|
||||
out.ClusterIPs = *(*[]string)(unsafe.Pointer(&in.ClusterIPs))
|
||||
out.IPFamilies = *(*[]v1.IPFamily)(unsafe.Pointer(&in.IPFamilies))
|
||||
out.IPFamilyPolicy = (*v1.IPFamilyPolicyType)(unsafe.Pointer(in.IPFamilyPolicy))
|
||||
out.IPFamilyPolicy = (*v1.IPFamilyPolicy)(unsafe.Pointer(in.IPFamilyPolicy))
|
||||
out.ExternalName = in.ExternalName
|
||||
out.ExternalIPs = *(*[]string)(unsafe.Pointer(&in.ExternalIPs))
|
||||
out.LoadBalancerIP = in.LoadBalancerIP
|
||||
@ -7995,6 +7999,9 @@ func autoConvert_v1_TopologySpreadConstraint_To_core_TopologySpreadConstraint(in
|
||||
out.WhenUnsatisfiable = core.UnsatisfiableConstraintAction(in.WhenUnsatisfiable)
|
||||
out.LabelSelector = (*metav1.LabelSelector)(unsafe.Pointer(in.LabelSelector))
|
||||
out.MinDomains = (*int32)(unsafe.Pointer(in.MinDomains))
|
||||
out.NodeAffinityPolicy = (*core.NodeInclusionPolicy)(unsafe.Pointer(in.NodeAffinityPolicy))
|
||||
out.NodeTaintsPolicy = (*core.NodeInclusionPolicy)(unsafe.Pointer(in.NodeTaintsPolicy))
|
||||
out.MatchLabelKeys = *(*[]string)(unsafe.Pointer(&in.MatchLabelKeys))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8009,6 +8016,9 @@ func autoConvert_core_TopologySpreadConstraint_To_v1_TopologySpreadConstraint(in
|
||||
out.WhenUnsatisfiable = v1.UnsatisfiableConstraintAction(in.WhenUnsatisfiable)
|
||||
out.LabelSelector = (*metav1.LabelSelector)(unsafe.Pointer(in.LabelSelector))
|
||||
out.MinDomains = (*int32)(unsafe.Pointer(in.MinDomains))
|
||||
out.NodeAffinityPolicy = (*v1.NodeInclusionPolicy)(unsafe.Pointer(in.NodeAffinityPolicy))
|
||||
out.NodeTaintsPolicy = (*v1.NodeInclusionPolicy)(unsafe.Pointer(in.NodeTaintsPolicy))
|
||||
out.MatchLabelKeys = *(*[]string)(unsafe.Pointer(&in.MatchLabelKeys))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/apis/core/validation/events.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/core/validation/events.go
generated
vendored
@ -40,7 +40,7 @@ const (
|
||||
|
||||
func ValidateEventCreate(event *core.Event, requestVersion schema.GroupVersion) field.ErrorList {
|
||||
// Make sure events always pass legacy validation.
|
||||
allErrs := legacyValidateEvent(event)
|
||||
allErrs := legacyValidateEvent(event, requestVersion)
|
||||
if requestVersion == v1.SchemeGroupVersion || requestVersion == eventsv1beta1.SchemeGroupVersion {
|
||||
// No further validation for backwards compatibility.
|
||||
return allErrs
|
||||
@ -73,7 +73,7 @@ func ValidateEventCreate(event *core.Event, requestVersion schema.GroupVersion)
|
||||
|
||||
func ValidateEventUpdate(newEvent, oldEvent *core.Event, requestVersion schema.GroupVersion) field.ErrorList {
|
||||
// Make sure the new event always passes legacy validation.
|
||||
allErrs := legacyValidateEvent(newEvent)
|
||||
allErrs := legacyValidateEvent(newEvent, requestVersion)
|
||||
if requestVersion == v1.SchemeGroupVersion || requestVersion == eventsv1beta1.SchemeGroupVersion {
|
||||
// No further validation for backwards compatibility.
|
||||
return allErrs
|
||||
@ -119,11 +119,16 @@ func validateV1EventSeries(event *core.Event) field.ErrorList {
|
||||
}
|
||||
|
||||
// legacyValidateEvent makes sure that the event makes sense.
|
||||
func legacyValidateEvent(event *core.Event) field.ErrorList {
|
||||
func legacyValidateEvent(event *core.Event, requestVersion schema.GroupVersion) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
// Because go
|
||||
zeroTime := time.Time{}
|
||||
|
||||
reportingControllerFieldName := "reportingController"
|
||||
if requestVersion == v1.SchemeGroupVersion {
|
||||
reportingControllerFieldName = "reportingComponent"
|
||||
}
|
||||
|
||||
// "New" Events need to have EventTime set, so it's validating old object.
|
||||
if event.EventTime.Time == zeroTime {
|
||||
// Make sure event.Namespace and the involvedInvolvedObject.Namespace agree
|
||||
@ -144,11 +149,9 @@ func legacyValidateEvent(event *core.Event) field.ErrorList {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
|
||||
}
|
||||
if len(event.ReportingController) == 0 {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("reportingController"), ""))
|
||||
}
|
||||
for _, msg := range validation.IsQualifiedName(event.ReportingController) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("reportingController"), event.ReportingController, msg))
|
||||
allErrs = append(allErrs, field.Required(field.NewPath(reportingControllerFieldName), ""))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(event.ReportingController, field.NewPath(reportingControllerFieldName))...)
|
||||
if len(event.ReportingInstance) == 0 {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("reportingInstance"), ""))
|
||||
}
|
||||
|
501
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
501
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
@ -45,7 +45,6 @@ import (
|
||||
schedulinghelper "k8s.io/component-helpers/scheduling/corev1"
|
||||
apiservice "k8s.io/kubernetes/pkg/api/service"
|
||||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
podshelper "k8s.io/kubernetes/pkg/apis/core/pods"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
@ -1530,6 +1529,26 @@ func validateStorageOSPersistentVolumeSource(storageos *core.StorageOSPersistent
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validatePVSecretReference check whether provided SecretReference object is valid in terms of secret name and namespace.
|
||||
|
||||
func validatePVSecretReference(secretRef *core.SecretReference, allowDNSSubDomainSecretName bool, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
if len(secretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
|
||||
} else if allowDNSSubDomainSecretName {
|
||||
allErrs = append(allErrs, ValidateDNS1123Subdomain(secretRef.Name, fldPath.Child("name"))...)
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(secretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
|
||||
if len(secretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(secretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateCSIDriverName(driverName string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@ -1548,7 +1567,7 @@ func ValidateCSIDriverName(driverName string, fldPath *field.Path) field.ErrorLi
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, allowDNSSubDomainSecretName bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
allErrs = append(allErrs, ValidateCSIDriverName(csi.Driver, fldPath.Child("driver"))...)
|
||||
@ -1556,46 +1575,18 @@ func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, fldP
|
||||
if len(csi.VolumeHandle) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("volumeHandle"), ""))
|
||||
}
|
||||
|
||||
if csi.ControllerPublishSecretRef != nil {
|
||||
if len(csi.ControllerPublishSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("controllerPublishSecretRef", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.ControllerPublishSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.ControllerPublishSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("controllerPublishSecretRef", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.ControllerPublishSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validatePVSecretReference(csi.ControllerPublishSecretRef, allowDNSSubDomainSecretName, fldPath.Child("controllerPublishSecretRef"))...)
|
||||
}
|
||||
|
||||
if csi.ControllerExpandSecretRef != nil {
|
||||
if len(csi.ControllerExpandSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("controllerExpandSecretRef", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.ControllerExpandSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.ControllerExpandSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("controllerExpandSecretRef", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.ControllerExpandSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validatePVSecretReference(csi.ControllerExpandSecretRef, allowDNSSubDomainSecretName, fldPath.Child("controllerExpandSecretRef"))...)
|
||||
}
|
||||
|
||||
if csi.NodePublishSecretRef != nil {
|
||||
if len(csi.NodePublishSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.NodePublishSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validatePVSecretReference(csi.NodePublishSecretRef, allowDNSSubDomainSecretName, fldPath.Child("nodePublishSecretRef"))...)
|
||||
}
|
||||
if csi.NodeExpandSecretRef != nil {
|
||||
allErrs = append(allErrs, validatePVSecretReference(csi.NodeExpandSecretRef, allowDNSSubDomainSecretName, fldPath.Child("nodeExpandSecretRef"))...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -1656,6 +1647,8 @@ var allowedPVCTemplateObjectMetaFields = map[string]bool{
|
||||
type PersistentVolumeSpecValidationOptions struct {
|
||||
// Allow spec to contain the "ReadWiteOncePod" access mode
|
||||
AllowReadWriteOncePod bool
|
||||
// Allow the secretRef Name field to be of DNSSubDomain Format
|
||||
AllowDNSSubDomainSecretName bool
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeName checks that a name is appropriate for a
|
||||
@ -1670,7 +1663,8 @@ var supportedVolumeModes = sets.NewString(string(core.PersistentVolumeBlock), st
|
||||
|
||||
func ValidationOptionsForPersistentVolume(pv, oldPv *core.PersistentVolume) PersistentVolumeSpecValidationOptions {
|
||||
opts := PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
AllowDNSSubDomainSecretName: false,
|
||||
}
|
||||
if oldPv == nil {
|
||||
// If there's no old PV, use the options based solely on feature enablement
|
||||
@ -1680,9 +1674,21 @@ func ValidationOptionsForPersistentVolume(pv, oldPv *core.PersistentVolume) Pers
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
if oldCSI := oldPv.Spec.CSI; oldCSI != nil {
|
||||
opts.AllowDNSSubDomainSecretName =
|
||||
secretRefRequiresSubdomainSecretName(oldCSI.ControllerExpandSecretRef) ||
|
||||
secretRefRequiresSubdomainSecretName(oldCSI.ControllerPublishSecretRef) ||
|
||||
secretRefRequiresSubdomainSecretName(oldCSI.NodeStageSecretRef) ||
|
||||
secretRefRequiresSubdomainSecretName(oldCSI.NodePublishSecretRef)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func secretRefRequiresSubdomainSecretName(secretRef *core.SecretReference) bool {
|
||||
// ref and name were specified and name didn't fit within label validation
|
||||
return secretRef != nil && len(secretRef.Name) > 0 && len(validation.IsDNS1123Label(secretRef.Name)) > 0
|
||||
}
|
||||
|
||||
func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName string, validateInlinePersistentVolumeSpec bool, fldPath *field.Path, opts PersistentVolumeSpecValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@ -1937,7 +1943,7 @@ func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName stri
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("csi"), "may not specify more than 1 volume type"))
|
||||
} else {
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateCSIPersistentVolumeSource(pvSpec.CSI, fldPath.Child("csi"))...)
|
||||
allErrs = append(allErrs, validateCSIPersistentVolumeSource(pvSpec.CSI, opts.AllowDNSSubDomainSecretName, fldPath.Child("csi"))...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2021,12 +2027,15 @@ type PersistentVolumeClaimSpecValidationOptions struct {
|
||||
AllowReadWriteOncePod bool
|
||||
// Allow users to recover from previously failing expansion operation
|
||||
EnableRecoverFromExpansionFailure bool
|
||||
// Allow assigning StorageClass to unbound PVCs retroactively
|
||||
EnableRetroactiveDefaultStorageClass bool
|
||||
}
|
||||
|
||||
func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolumeClaim) PersistentVolumeClaimSpecValidationOptions {
|
||||
opts := PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
EnableRecoverFromExpansionFailure: utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure),
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
EnableRecoverFromExpansionFailure: utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure),
|
||||
EnableRetroactiveDefaultStorageClass: utilfeature.DefaultFeatureGate.Enabled(features.RetroactiveDefaultStorageClass),
|
||||
}
|
||||
if oldPvc == nil {
|
||||
// If there's no old PVC, use the options based solely on feature enablement
|
||||
@ -2162,7 +2171,7 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeCl
|
||||
oldPvcClone.Spec.VolumeName = newPvcClone.Spec.VolumeName // +k8s:verify-mutation:reason=clone
|
||||
}
|
||||
|
||||
if validateStorageClassUpgrade(oldPvcClone.Annotations, newPvcClone.Annotations,
|
||||
if validateStorageClassUpgradeFromAnnotation(oldPvcClone.Annotations, newPvcClone.Annotations,
|
||||
oldPvcClone.Spec.StorageClassName, newPvcClone.Spec.StorageClassName) {
|
||||
newPvcClone.Spec.StorageClassName = nil
|
||||
metav1.SetMetaDataAnnotation(&newPvcClone.ObjectMeta, core.BetaStorageClassAnnotation, oldPvcClone.Annotations[core.BetaStorageClassAnnotation])
|
||||
@ -2170,6 +2179,13 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeCl
|
||||
// storageclass annotation should be immutable after creation
|
||||
// TODO: remove Beta when no longer needed
|
||||
allErrs = append(allErrs, ValidateImmutableAnnotation(newPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], oldPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], v1.BetaStorageClassAnnotation, field.NewPath("metadata"))...)
|
||||
|
||||
// If update from annotation to attribute failed we can attempt try to validate update from nil value.
|
||||
if validateStorageClassUpgradeFromNil(oldPvc.Annotations, oldPvc.Spec.StorageClassName, newPvc.Spec.StorageClassName, opts) {
|
||||
newPvcClone.Spec.StorageClassName = oldPvcClone.Spec.StorageClassName // +k8s:verify-mutation:reason=clone
|
||||
}
|
||||
// TODO: add a specific error with a hint that storage class name can not be changed
|
||||
// (instead of letting spec comparison below return generic field forbidden error)
|
||||
}
|
||||
|
||||
// lets make sure storage values are same.
|
||||
@ -2210,7 +2226,7 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeCl
|
||||
// 2. The old pvc's StorageClassName is not set
|
||||
// 3. The new pvc's StorageClassName is set and equal to the old value in annotation
|
||||
// 4. If the new pvc's StorageClassAnnotation is set,it must be equal to the old pv/pvc's StorageClassAnnotation
|
||||
func validateStorageClassUpgrade(oldAnnotations, newAnnotations map[string]string, oldScName, newScName *string) bool {
|
||||
func validateStorageClassUpgradeFromAnnotation(oldAnnotations, newAnnotations map[string]string, oldScName, newScName *string) bool {
|
||||
oldSc, oldAnnotationExist := oldAnnotations[core.BetaStorageClassAnnotation]
|
||||
newScInAnnotation, newAnnotationExist := newAnnotations[core.BetaStorageClassAnnotation]
|
||||
return oldAnnotationExist /* condition 1 */ &&
|
||||
@ -2219,6 +2235,20 @@ func validateStorageClassUpgrade(oldAnnotations, newAnnotations map[string]strin
|
||||
(!newAnnotationExist || newScInAnnotation == oldSc) /* condition 4 */
|
||||
}
|
||||
|
||||
// Provide an upgrade path from PVC with nil storage class. We allow update of
|
||||
// StorageClassName only if following four conditions are met at the same time:
|
||||
// 1. RetroactiveDefaultStorageClass FeatureGate is enabled
|
||||
// 2. The new pvc's StorageClassName is not nil
|
||||
// 3. The old pvc's StorageClassName is nil
|
||||
// 4. The old pvc either does not have beta annotation set, or the beta annotation matches new pvc's StorageClassName
|
||||
func validateStorageClassUpgradeFromNil(oldAnnotations map[string]string, oldScName, newScName *string, opts PersistentVolumeClaimSpecValidationOptions) bool {
|
||||
oldAnnotation, oldAnnotationExist := oldAnnotations[core.BetaStorageClassAnnotation]
|
||||
return opts.EnableRetroactiveDefaultStorageClass /* condition 1 */ &&
|
||||
newScName != nil /* condition 2 */ &&
|
||||
oldScName == nil /* condition 3 */ &&
|
||||
(!oldAnnotationExist || *newScName == oldAnnotation) /* condition 4 */
|
||||
}
|
||||
|
||||
var resizeStatusSet = sets.NewString(string(core.PersistentVolumeClaimNoExpansionInProgress),
|
||||
string(core.PersistentVolumeClaimControllerExpansionInProgress),
|
||||
string(core.PersistentVolumeClaimControllerExpansionFailed),
|
||||
@ -2405,13 +2435,9 @@ func validateObjectFieldSelector(fs *core.ObjectFieldSelector, expressions *sets
|
||||
if path, subscript, ok := fieldpath.SplitMaybeSubscriptedPath(internalFieldPath); ok {
|
||||
switch path {
|
||||
case "metadata.annotations":
|
||||
for _, msg := range validation.IsQualifiedName(strings.ToLower(subscript)) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subscript, msg))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(strings.ToLower(subscript), fldPath)...)
|
||||
case "metadata.labels":
|
||||
for _, msg := range validation.IsQualifiedName(subscript) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subscript, msg))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(subscript, fldPath)...)
|
||||
default:
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, path, "does not support subscript"))
|
||||
}
|
||||
@ -2905,6 +2931,8 @@ func validatePullPolicy(policy core.PullPolicy, fldPath *field.Path) field.Error
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// validateEphemeralContainers is called by pod spec and template validation to validate the list of ephemeral containers.
|
||||
// Note that this is called for pod template even though ephemeral containers aren't allowed in pod templates.
|
||||
func validateEphemeralContainers(ephemeralContainers []core.EphemeralContainer, containers, initContainers []core.Container, volumes map[string]core.VolumeSource, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@ -2912,44 +2940,40 @@ func validateEphemeralContainers(ephemeralContainers []core.EphemeralContainer,
|
||||
return allErrs
|
||||
}
|
||||
|
||||
allNames := sets.String{}
|
||||
otherNames, allNames := sets.String{}, sets.String{}
|
||||
for _, c := range containers {
|
||||
otherNames.Insert(c.Name)
|
||||
allNames.Insert(c.Name)
|
||||
}
|
||||
for _, c := range initContainers {
|
||||
otherNames.Insert(c.Name)
|
||||
allNames.Insert(c.Name)
|
||||
}
|
||||
|
||||
for i, ec := range ephemeralContainers {
|
||||
idxPath := fldPath.Index(i)
|
||||
|
||||
if ec.TargetContainerName != "" && !allNames.Has(ec.TargetContainerName) {
|
||||
allErrs = append(allErrs, field.NotFound(idxPath.Child("targetContainerName"), ec.TargetContainerName))
|
||||
}
|
||||
|
||||
if ec.Name == "" {
|
||||
allErrs = append(allErrs, field.Required(idxPath, "ephemeralContainer requires a name"))
|
||||
continue
|
||||
}
|
||||
|
||||
// Using validateContainers() here isn't ideal because it adds an index to the error message that
|
||||
// doesn't really exist for EphemeralContainers (i.e. ephemeralContainers[0].spec[0].name instead
|
||||
// of ephemeralContainers[0].spec.name)
|
||||
// TODO(verb): factor a validateContainer() out of validateContainers() to be used here
|
||||
c := core.Container(ec.EphemeralContainerCommon)
|
||||
allErrs = append(allErrs, validateContainers([]core.Container{c}, false, volumes, idxPath, opts)...)
|
||||
// EphemeralContainers don't require the backwards-compatibility distinction between pod/podTemplate validation
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod([]core.Container{c}, idxPath)...)
|
||||
c := (*core.Container)(&ec.EphemeralContainerCommon)
|
||||
allErrs = append(allErrs, validateContainerCommon(c, volumes, idxPath, opts)...)
|
||||
// Ephemeral containers don't need looser constraints for pod templates, so it's convenient to apply both validations
|
||||
// here where we've already converted EphemeralContainerCommon to Container.
|
||||
allErrs = append(allErrs, validateContainerOnlyForPod(c, idxPath)...)
|
||||
|
||||
// Ephemeral containers must have a name unique across all container types.
|
||||
if allNames.Has(ec.Name) {
|
||||
allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), ec.Name))
|
||||
} else {
|
||||
allNames.Insert(ec.Name)
|
||||
}
|
||||
|
||||
// Ephemeral Containers should not be relied upon for fundamental pod services, so fields such as
|
||||
// The target container name must exist and be non-ephemeral.
|
||||
if ec.TargetContainerName != "" && !otherNames.Has(ec.TargetContainerName) {
|
||||
allErrs = append(allErrs, field.NotFound(idxPath.Child("targetContainerName"), ec.TargetContainerName))
|
||||
}
|
||||
|
||||
// Ephemeral containers should not be relied upon for fundamental pod services, so fields such as
|
||||
// Lifecycle, probes, resources and ports should be disallowed. This is implemented as a list
|
||||
// of allowed fields so that new fields will be given consideration prior to inclusion in Ephemeral Containers.
|
||||
// of allowed fields so that new fields will be given consideration prior to inclusion in ephemeral containers.
|
||||
allErrs = append(allErrs, validateFieldAllowList(ec.EphemeralContainerCommon, allowedEphemeralContainerFields, "cannot be set for an Ephemeral Container", idxPath)...)
|
||||
|
||||
// VolumeMount subpaths have the potential to leak resources since they're implemented with bind mounts
|
||||
@ -2991,41 +3015,142 @@ func validateFieldAllowList(value interface{}, allowedFields map[string]bool, er
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateInitContainers(containers []core.Container, otherContainers []core.Container, deviceVolumes map[string]core.VolumeSource, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
// validateInitContainers is called by pod spec and template validation to validate the list of init containers
|
||||
func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
if len(containers) > 0 {
|
||||
allErrs = append(allErrs, validateContainers(containers, true, deviceVolumes, fldPath, opts)...)
|
||||
}
|
||||
|
||||
allNames := sets.String{}
|
||||
for _, ctr := range otherContainers {
|
||||
for _, ctr := range regularContainers {
|
||||
allNames.Insert(ctr.Name)
|
||||
}
|
||||
for i, ctr := range containers {
|
||||
idxPath := fldPath.Index(i)
|
||||
|
||||
// Apply the validation common to all container types
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, idxPath, opts)...)
|
||||
|
||||
// Names must be unique within regular and init containers. Collisions with ephemeral containers
|
||||
// will be detected by validateEphemeralContainers().
|
||||
if allNames.Has(ctr.Name) {
|
||||
allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), ctr.Name))
|
||||
}
|
||||
if len(ctr.Name) > 0 {
|
||||
} else if len(ctr.Name) > 0 {
|
||||
allNames.Insert(ctr.Name)
|
||||
}
|
||||
|
||||
// Check for port conflicts in init containers individually since init containers run one-by-one.
|
||||
allErrs = append(allErrs, checkHostPortConflicts([]core.Container{ctr}, fldPath)...)
|
||||
|
||||
// These fields are disallowed for init containers.
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("lifecycle"), ctr.Lifecycle, "must not be set for init containers"))
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("lifecycle"), "may not be set for init containers"))
|
||||
}
|
||||
if ctr.LivenessProbe != nil {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe"), ctr.LivenessProbe, "must not be set for init containers"))
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("livenessProbe"), "may not be set for init containers"))
|
||||
}
|
||||
if ctr.ReadinessProbe != nil {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("readinessProbe"), ctr.ReadinessProbe, "must not be set for init containers"))
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("readinessProbe"), "may not be set for init containers"))
|
||||
}
|
||||
if ctr.StartupProbe != nil {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe"), ctr.StartupProbe, "must not be set for init containers"))
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("startupProbe"), "may not be set for init containers"))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateContainers(containers []core.Container, isInitContainers bool, volumes map[string]core.VolumeSource, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
// validateContainerCommon applies validation common to all container types. It's called by regular, init, and ephemeral
|
||||
// container list validation to require a properly formatted name, image, etc.
|
||||
func validateContainerCommon(ctr *core.Container, volumes map[string]core.VolumeSource, path *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
namePath := path.Child("name")
|
||||
if len(ctr.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(namePath, ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(ctr.Name, namePath)...)
|
||||
}
|
||||
|
||||
// TODO: do not validate leading and trailing whitespace to preserve backward compatibility.
|
||||
// for example: https://github.com/openshift/origin/issues/14659 image = " " is special token in pod template
|
||||
// others may have done similar
|
||||
if len(ctr.Image) == 0 {
|
||||
allErrs = append(allErrs, field.Required(path.Child("image"), ""))
|
||||
}
|
||||
|
||||
switch ctr.TerminationMessagePolicy {
|
||||
case core.TerminationMessageReadFile, core.TerminationMessageFallbackToLogsOnError:
|
||||
case "":
|
||||
allErrs = append(allErrs, field.Required(path.Child("terminationMessagePolicy"), ""))
|
||||
default:
|
||||
supported := []string{
|
||||
string(core.TerminationMessageReadFile),
|
||||
string(core.TerminationMessageFallbackToLogsOnError),
|
||||
}
|
||||
allErrs = append(allErrs, field.NotSupported(path.Child("terminationMessagePolicy"), ctr.TerminationMessagePolicy, supported))
|
||||
}
|
||||
|
||||
volMounts := GetVolumeMountMap(ctr.VolumeMounts)
|
||||
volDevices := GetVolumeDeviceMap(ctr.VolumeDevices)
|
||||
allErrs = append(allErrs, validateContainerPorts(ctr.Ports, path.Child("ports"))...)
|
||||
allErrs = append(allErrs, ValidateEnv(ctr.Env, path.Child("env"), opts)...)
|
||||
allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, path.Child("envFrom"))...)
|
||||
allErrs = append(allErrs, ValidateVolumeMounts(ctr.VolumeMounts, volDevices, volumes, ctr, path.Child("volumeMounts"))...)
|
||||
allErrs = append(allErrs, ValidateVolumeDevices(ctr.VolumeDevices, volMounts, volumes, path.Child("volumeDevices"))...)
|
||||
allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, path.Child("imagePullPolicy"))...)
|
||||
allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, path.Child("resources"), opts)...)
|
||||
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, path.Child("securityContext"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateHostUsers(spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// Only make the following checks if hostUsers is false (otherwise, the container uses the
|
||||
// same userns as the host, and so there isn't anything to check).
|
||||
if spec.SecurityContext == nil || spec.SecurityContext.HostUsers == nil || *spec.SecurityContext.HostUsers == true {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// For now only these volumes are supported:
|
||||
// - configmap
|
||||
// - secret
|
||||
// - downwardAPI
|
||||
// - emptyDir
|
||||
// - projected
|
||||
// So reject anything else.
|
||||
for i, vol := range spec.Volumes {
|
||||
switch {
|
||||
case vol.EmptyDir != nil:
|
||||
case vol.Secret != nil:
|
||||
case vol.DownwardAPI != nil:
|
||||
case vol.ConfigMap != nil:
|
||||
case vol.Projected != nil:
|
||||
default:
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("volumes").Index(i), "volume type not supported when `pod.Spec.HostUsers` is false"))
|
||||
}
|
||||
}
|
||||
|
||||
// We decided to restrict the usage of userns with other host namespaces:
|
||||
// https://github.com/kubernetes/kubernetes/pull/111090#discussion_r935994282
|
||||
// The tl;dr is: you can easily run into permission issues that seem unexpected, we don't
|
||||
// know of any good use case and we can always enable them later.
|
||||
|
||||
// Note we already validated above spec.SecurityContext is not nil.
|
||||
if spec.SecurityContext.HostNetwork {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("hostNetwork"), "when `pod.Spec.HostUsers` is false"))
|
||||
}
|
||||
if spec.SecurityContext.HostPID {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("HostPID"), "when `pod.Spec.HostUsers` is false"))
|
||||
}
|
||||
if spec.SecurityContext.HostIPC {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("HostIPC"), "when `pod.Spec.HostUsers` is false"))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateContainers is called by pod spec and template validation to validate the list of regular containers.
|
||||
func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(containers) == 0 {
|
||||
@ -3034,74 +3159,41 @@ func validateContainers(containers []core.Container, isInitContainers bool, volu
|
||||
|
||||
allNames := sets.String{}
|
||||
for i, ctr := range containers {
|
||||
idxPath := fldPath.Index(i)
|
||||
namePath := idxPath.Child("name")
|
||||
volMounts := GetVolumeMountMap(ctr.VolumeMounts)
|
||||
volDevices := GetVolumeDeviceMap(ctr.VolumeDevices)
|
||||
path := fldPath.Index(i)
|
||||
|
||||
if len(ctr.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(namePath, ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(ctr.Name, namePath)...)
|
||||
}
|
||||
// Apply validation common to all containers
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, path, opts)...)
|
||||
|
||||
// Container names must be unique within the list of regular containers.
|
||||
// Collisions with init or ephemeral container names will be detected by the init or ephemeral
|
||||
// container validation to prevent duplicate error messages.
|
||||
if allNames.Has(ctr.Name) {
|
||||
allErrs = append(allErrs, field.Duplicate(namePath, ctr.Name))
|
||||
allErrs = append(allErrs, field.Duplicate(path.Child("name"), ctr.Name))
|
||||
} else {
|
||||
allNames.Insert(ctr.Name)
|
||||
}
|
||||
// TODO: do not validate leading and trailing whitespace to preserve backward compatibility.
|
||||
// for example: https://github.com/openshift/origin/issues/14659 image = " " is special token in pod template
|
||||
// others may have done similar
|
||||
if len(ctr.Image) == 0 {
|
||||
allErrs = append(allErrs, field.Required(idxPath.Child("image"), ""))
|
||||
}
|
||||
|
||||
// These fields are only allowed for regular containers, so only check supported values here.
|
||||
// Init and ephemeral container validation will return field.Forbidden() for these paths.
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, idxPath.Child("lifecycle"))...)
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, path.Child("lifecycle"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.LivenessProbe, idxPath.Child("livenessProbe"))...)
|
||||
// Readiness-specific validation
|
||||
if ctr.ReadinessProbe != nil && ctr.ReadinessProbe.TerminationGracePeriodSeconds != nil {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("readinessProbe", "terminationGracePeriodSeconds"), ctr.ReadinessProbe.TerminationGracePeriodSeconds, "must not be set for readinessProbes"))
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
|
||||
// Liveness-specific validation
|
||||
allErrs = append(allErrs, validateProbe(ctr.LivenessProbe, path.Child("livenessProbe"))...)
|
||||
if ctr.LivenessProbe != nil && ctr.LivenessProbe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1"))
|
||||
allErrs = append(allErrs, field.Invalid(path.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
|
||||
// Startup-specific validation
|
||||
allErrs = append(allErrs, validateProbe(ctr.ReadinessProbe, path.Child("readinessProbe"))...)
|
||||
if ctr.ReadinessProbe != nil && ctr.ReadinessProbe.TerminationGracePeriodSeconds != nil {
|
||||
allErrs = append(allErrs, field.Invalid(path.Child("readinessProbe", "terminationGracePeriodSeconds"), ctr.ReadinessProbe.TerminationGracePeriodSeconds, "must not be set for readinessProbes"))
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, path.Child("startupProbe"))...)
|
||||
if ctr.StartupProbe != nil && ctr.StartupProbe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
|
||||
allErrs = append(allErrs, field.Invalid(path.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
|
||||
switch ctr.TerminationMessagePolicy {
|
||||
case core.TerminationMessageReadFile, core.TerminationMessageFallbackToLogsOnError:
|
||||
case "":
|
||||
allErrs = append(allErrs, field.Required(idxPath.Child("terminationMessagePolicy"), "must be 'File' or 'FallbackToLogsOnError'"))
|
||||
default:
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("terminationMessagePolicy"), ctr.TerminationMessagePolicy, "must be 'File' or 'FallbackToLogsOnError'"))
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, validateProbe(ctr.ReadinessProbe, idxPath.Child("readinessProbe"))...)
|
||||
allErrs = append(allErrs, validateContainerPorts(ctr.Ports, idxPath.Child("ports"))...)
|
||||
allErrs = append(allErrs, ValidateEnv(ctr.Env, idxPath.Child("env"), opts)...)
|
||||
allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, idxPath.Child("envFrom"))...)
|
||||
allErrs = append(allErrs, ValidateVolumeMounts(ctr.VolumeMounts, volDevices, volumes, &ctr, idxPath.Child("volumeMounts"))...)
|
||||
allErrs = append(allErrs, ValidateVolumeDevices(ctr.VolumeDevices, volMounts, volumes, idxPath.Child("volumeDevices"))...)
|
||||
allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, idxPath.Child("imagePullPolicy"))...)
|
||||
allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, idxPath.Child("resources"), opts)...)
|
||||
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, idxPath.Child("securityContext"))...)
|
||||
}
|
||||
|
||||
if isInitContainers {
|
||||
// check initContainers one by one since they are running in sequential order.
|
||||
for _, initContainer := range containers {
|
||||
allErrs = append(allErrs, checkHostPortConflicts([]core.Container{initContainer}, fldPath)...)
|
||||
}
|
||||
} else {
|
||||
// Check for colliding ports across all containers.
|
||||
allErrs = append(allErrs, checkHostPortConflicts(containers, fldPath)...)
|
||||
}
|
||||
// Port conflicts are checked across all containers
|
||||
allErrs = append(allErrs, checkHostPortConflicts(containers, fldPath)...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
@ -3175,9 +3267,7 @@ const (
|
||||
func validateReadinessGates(readinessGates []core.PodReadinessGate, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for i, value := range readinessGates {
|
||||
for _, msg := range validation.IsQualifiedName(string(value.ConditionType)) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("conditionType"), string(value.ConditionType), msg))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(string(value.ConditionType), fldPath.Index(i).Child("conditionType"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -3389,14 +3479,22 @@ func ValidateTolerations(tolerations []core.Toleration, fldPath *field.Path) fie
|
||||
}
|
||||
|
||||
// validateContainersOnlyForPod does additional validation for containers on a pod versus a pod template
|
||||
// it only does additive validation of fields not covered in validateContainers
|
||||
// it only does additive validation of fields not covered in validateContainers and is not called for
|
||||
// ephemeral containers which require a conversion to core.Container.
|
||||
func validateContainersOnlyForPod(containers []core.Container, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for i, ctr := range containers {
|
||||
idxPath := fldPath.Index(i)
|
||||
if len(ctr.Image) != len(strings.TrimSpace(ctr.Image)) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("image"), ctr.Image, "must not have leading or trailing whitespace"))
|
||||
}
|
||||
allErrs = append(allErrs, validateContainerOnlyForPod(&ctr, fldPath.Index(i))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateContainerOnlyForPod does pod-only (i.e. not pod template) validation for a single container.
|
||||
// This is called by validateContainersOnlyForPod and validateEphemeralContainers directly.
|
||||
func validateContainerOnlyForPod(ctr *core.Container, path *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(ctr.Image) != len(strings.TrimSpace(ctr.Image)) {
|
||||
allErrs = append(allErrs, field.Invalid(path.Child("image"), ctr.Image, "must not have leading or trailing whitespace"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -3413,10 +3511,6 @@ type PodValidationOptions struct {
|
||||
AllowWindowsHostProcessField bool
|
||||
// Allow more DNSSearchPaths and longer DNSSearchListChars
|
||||
AllowExpandedDNSConfig bool
|
||||
// Allow OSField to be set in the pod spec
|
||||
AllowOSField bool
|
||||
// Allow sysctl name to contain a slash
|
||||
AllowSysctlRegexContainSlash bool
|
||||
}
|
||||
|
||||
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
|
||||
@ -3447,6 +3541,7 @@ func validatePodMetadataAndSpec(pod *core.Pod, opts PodValidationOptions) field.
|
||||
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.Containers, specPath.Child("containers"))...)
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)
|
||||
// validateContainersOnlyForPod() is checked for ephemeral containers by validateEphemeralContainers()
|
||||
|
||||
return allErrs
|
||||
}
|
||||
@ -3507,7 +3602,7 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
|
||||
|
||||
vols, vErrs := ValidateVolumes(spec.Volumes, podMeta, fldPath.Child("volumes"), opts)
|
||||
allErrs = append(allErrs, vErrs...)
|
||||
allErrs = append(allErrs, validateContainers(spec.Containers, false, vols, fldPath.Child("containers"), opts)...)
|
||||
allErrs = append(allErrs, validateContainers(spec.Containers, vols, fldPath.Child("containers"), opts)...)
|
||||
allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, fldPath.Child("initContainers"), opts)...)
|
||||
allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, fldPath.Child("ephemeralContainers"), opts)...)
|
||||
allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy, fldPath.Child("restartPolicy"))...)
|
||||
@ -3520,6 +3615,7 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
|
||||
allErrs = append(allErrs, validateReadinessGates(spec.ReadinessGates, fldPath.Child("readinessGates"))...)
|
||||
allErrs = append(allErrs, validateTopologySpreadConstraints(spec.TopologySpreadConstraints, fldPath.Child("topologySpreadConstraints"))...)
|
||||
allErrs = append(allErrs, validateWindowsHostProcessPod(spec, fldPath, opts)...)
|
||||
allErrs = append(allErrs, validateHostUsers(spec, fldPath)...)
|
||||
if len(spec.ServiceAccountName) > 0 {
|
||||
for _, msg := range ValidateServiceAccountName(spec.ServiceAccountName, false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceAccountName"), spec.ServiceAccountName, msg))
|
||||
@ -3612,6 +3708,9 @@ func validateWindows(spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
|
||||
if securityContext.SELinuxOptions != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("securityContext").Child("seLinuxOptions"), "cannot be set for a windows pod"))
|
||||
}
|
||||
if securityContext.HostUsers != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("hostUsers"), "cannot be set for a windows pod"))
|
||||
}
|
||||
if securityContext.HostPID {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("hostPID"), "cannot be set for a windows pod"))
|
||||
}
|
||||
@ -4075,9 +4174,6 @@ 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
|
||||
|
||||
// a sysctl name regex with slash allowed
|
||||
SysctlContainSlashFmt string = "(" + SysctlSegmentFmt + "[\\./])*" + SysctlSegmentFmt
|
||||
|
||||
@ -4085,41 +4181,29 @@ const (
|
||||
SysctlMaxLength int = 253
|
||||
)
|
||||
|
||||
var sysctlRegexp = regexp.MustCompile("^" + SysctlFmt + "$")
|
||||
|
||||
var sysctlContainSlashRegexp = regexp.MustCompile("^" + SysctlContainSlashFmt + "$")
|
||||
|
||||
// IsValidSysctlName checks that the given string is a valid sysctl name,
|
||||
// i.e. matches SysctlFmt (or SysctlContainSlashFmt if canContainSlash is true).
|
||||
// i.e. matches SysctlContainSlashFmt.
|
||||
// More info:
|
||||
// https://man7.org/linux/man-pages/man8/sysctl.8.html
|
||||
// https://man7.org/linux/man-pages/man5/sysctl.d.5.html
|
||||
func IsValidSysctlName(name string, canContainSlash bool) bool {
|
||||
//
|
||||
// https://man7.org/linux/man-pages/man8/sysctl.8.html
|
||||
// https://man7.org/linux/man-pages/man5/sysctl.d.5.html
|
||||
func IsValidSysctlName(name string) bool {
|
||||
if len(name) > SysctlMaxLength {
|
||||
return false
|
||||
}
|
||||
if canContainSlash {
|
||||
return sysctlContainSlashRegexp.MatchString(name)
|
||||
}
|
||||
return sysctlRegexp.MatchString(name)
|
||||
return sysctlContainSlashRegexp.MatchString(name)
|
||||
}
|
||||
|
||||
func getSysctlFmt(canContainSlash bool) string {
|
||||
if canContainSlash {
|
||||
// use relaxed validation everywhere in 1.24
|
||||
return SysctlContainSlashFmt
|
||||
}
|
||||
// Will be removed in 1.24
|
||||
return SysctlFmt
|
||||
}
|
||||
func validateSysctls(sysctls []core.Sysctl, fldPath *field.Path, allowSysctlRegexContainSlash bool) field.ErrorList {
|
||||
func validateSysctls(sysctls []core.Sysctl, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
names := make(map[string]struct{})
|
||||
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, allowSysctlRegexContainSlash) {
|
||||
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, getSysctlFmt(allowSysctlRegexContainSlash))))
|
||||
} 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, sysctlContainSlashRegexp)))
|
||||
} else if _, ok := names[s.Name]; ok {
|
||||
allErrs = append(allErrs, field.Duplicate(fldPath.Index(i).Child("name"), s.Name))
|
||||
}
|
||||
@ -4159,7 +4243,7 @@ func ValidatePodSecurityContext(securityContext *core.PodSecurityContext, spec *
|
||||
}
|
||||
|
||||
if len(securityContext.Sysctls) != 0 {
|
||||
allErrs = append(allErrs, validateSysctls(securityContext.Sysctls, fldPath.Child("sysctls"), opts.AllowSysctlRegexContainSlash)...)
|
||||
allErrs = append(allErrs, validateSysctls(securityContext.Sysctls, fldPath.Child("sysctls"))...)
|
||||
}
|
||||
|
||||
if securityContext.FSGroupChangePolicy != nil {
|
||||
@ -4208,7 +4292,7 @@ func ValidatePodCreate(pod *core.Pod, opts PodValidationOptions) field.ErrorList
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateSeccompAnnotationsAndFields iterates through all containers and ensure that when both seccompProfile and seccomp annotations exist they match.
|
||||
// validateSeccompAnnotationsAndFields iterates through all containers and ensure that when both seccompProfile and seccomp annotations exist they match.
|
||||
func validateSeccompAnnotationsAndFields(objectMeta metav1.ObjectMeta, podSpec *core.PodSpec, specPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@ -4435,9 +4519,7 @@ func validatePodConditions(conditions []core.PodCondition, fldPath *field.Path)
|
||||
if systemConditions.Has(string(condition.Type)) {
|
||||
continue
|
||||
}
|
||||
for _, msg := range validation.IsQualifiedName(string(condition.Type)) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("Type"), string(condition.Type), msg))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(string(condition.Type), fldPath.Index(i).Child("Type"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -4719,9 +4801,7 @@ func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService bo
|
||||
allErrs = append(allErrs, ValidatePortNumOrName(sp.TargetPort, fldPath.Child("targetPort"))...)
|
||||
|
||||
if sp.AppProtocol != nil {
|
||||
for _, msg := range validation.IsQualifiedName(*sp.AppProtocol) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("appProtocol"), sp.AppProtocol, msg))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(*sp.AppProtocol, fldPath.Child("appProtocol"))...)
|
||||
}
|
||||
|
||||
// in the v1 API, targetPorts on headless services were tolerated.
|
||||
@ -4736,7 +4816,7 @@ func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService bo
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func needsExternalTrafficPolicy(svc *api.Service) bool {
|
||||
func needsExternalTrafficPolicy(svc *core.Service) bool {
|
||||
return svc.Spec.Type == core.ServiceTypeLoadBalancer || svc.Spec.Type == core.ServiceTypeNodePort
|
||||
}
|
||||
|
||||
@ -4781,7 +4861,7 @@ func validateServiceExternalTrafficPolicy(service *core.Service) field.ErrorList
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateServiceExternalTrafficFieldsUpdate(before, after *api.Service) field.ErrorList {
|
||||
func validateServiceExternalTrafficFieldsUpdate(before, after *core.Service) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if apiservice.NeedsHealthCheck(before) && apiservice.NeedsHealthCheck(after) {
|
||||
@ -6120,9 +6200,7 @@ func validateEndpointPort(port *core.EndpointPort, requireName bool, fldPath *fi
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), port.Protocol, supportedPortProtocols.List()))
|
||||
}
|
||||
if port.AppProtocol != nil {
|
||||
for _, msg := range validation.IsQualifiedName(*port.AppProtocol) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("appProtocol"), port.AppProtocol, msg))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateQualifiedName(*port.AppProtocol, fldPath.Child("appProtocol"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -6386,9 +6464,6 @@ func validateOS(podSpec *core.PodSpec, fldPath *field.Path, opts PodValidationOp
|
||||
if os == nil {
|
||||
return allErrs
|
||||
}
|
||||
if !opts.AllowOSField {
|
||||
return append(allErrs, field.Forbidden(fldPath, "cannot be set when IdentifyPodOS feature is not enabled"))
|
||||
}
|
||||
if len(os.Name) == 0 {
|
||||
return append(allErrs, field.Required(fldPath.Child("name"), "cannot be empty"))
|
||||
}
|
||||
@ -6513,6 +6588,13 @@ func validateTopologySpreadConstraints(constraints []core.TopologySpreadConstrai
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
allErrs = append(allErrs, validateMinDomains(subFldPath.Child("minDomains"), constraint.MinDomains, constraint.WhenUnsatisfiable)...)
|
||||
if err := validateNodeInclusionPolicy(subFldPath.Child("nodeAffinityPolicy"), constraint.NodeAffinityPolicy); err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
if err := validateNodeInclusionPolicy(subFldPath.Child("nodeTaintsPolicy"), constraint.NodeTaintsPolicy); err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
allErrs = append(allErrs, validateMatchLabelKeys(subFldPath.Child("matchLabelKeys"), constraint.MatchLabelKeys, constraint.LabelSelector)...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
@ -6570,6 +6652,49 @@ func ValidateSpreadConstraintNotRepeat(fldPath *field.Path, constraint core.Topo
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
supportedPodTopologySpreadNodePolicies = sets.NewString(string(core.NodeInclusionPolicyIgnore), string(core.NodeInclusionPolicyHonor))
|
||||
)
|
||||
|
||||
// validateNodeAffinityPolicy tests that the argument is a valid NodeInclusionPolicy.
|
||||
func validateNodeInclusionPolicy(fldPath *field.Path, policy *core.NodeInclusionPolicy) *field.Error {
|
||||
if policy == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !supportedPodTopologySpreadNodePolicies.Has(string(*policy)) {
|
||||
return field.NotSupported(fldPath, policy, supportedPodTopologySpreadNodePolicies.List())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateMatchLabelKeys tests that the elements are a valid label name and are not already included in labelSelector.
|
||||
func validateMatchLabelKeys(fldPath *field.Path, matchLabelKeys []string, labelSelector *metav1.LabelSelector) field.ErrorList {
|
||||
if len(matchLabelKeys) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
labelSelectorKeys := sets.String{}
|
||||
if labelSelector != nil {
|
||||
for key := range labelSelector.MatchLabels {
|
||||
labelSelectorKeys.Insert(key)
|
||||
}
|
||||
for _, matchExpression := range labelSelector.MatchExpressions {
|
||||
labelSelectorKeys.Insert(matchExpression.Key)
|
||||
}
|
||||
}
|
||||
|
||||
allErrs := field.ErrorList{}
|
||||
for i, key := range matchLabelKeys {
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabelName(key, fldPath.Index(i))...)
|
||||
if labelSelectorKeys.Has(key) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), key, "exists in both matchLabelKeys and labelSelector"))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateServiceClusterIPsRelatedFields validates .spec.ClusterIPs,,
|
||||
// .spec.IPFamilies, .spec.ipFamilyPolicy. This is exported because it is used
|
||||
// during IP init and allocation.
|
||||
|
27
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
27
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
@ -243,6 +243,11 @@ func (in *CSIPersistentVolumeSource) DeepCopyInto(out *CSIPersistentVolumeSource
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.NodeExpandSecretRef != nil {
|
||||
in, out := &in.NodeExpandSecretRef, &out.NodeExpandSecretRef
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -3731,6 +3736,11 @@ func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) {
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.HostUsers != nil {
|
||||
in, out := &in.HostUsers, &out.HostUsers
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.SELinuxOptions != nil {
|
||||
in, out := &in.SELinuxOptions, &out.SELinuxOptions
|
||||
*out = new(SELinuxOptions)
|
||||
@ -5370,7 +5380,7 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) {
|
||||
}
|
||||
if in.IPFamilyPolicy != nil {
|
||||
in, out := &in.IPFamilyPolicy, &out.IPFamilyPolicy
|
||||
*out = new(IPFamilyPolicyType)
|
||||
*out = new(IPFamilyPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExternalIPs != nil {
|
||||
@ -5634,6 +5644,21 @@ func (in *TopologySpreadConstraint) DeepCopyInto(out *TopologySpreadConstraint)
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.NodeAffinityPolicy != nil {
|
||||
in, out := &in.NodeAffinityPolicy, &out.NodeAffinityPolicy
|
||||
*out = new(NodeInclusionPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.NodeTaintsPolicy != nil {
|
||||
in, out := &in.NodeTaintsPolicy, &out.NodeTaintsPolicy
|
||||
*out = new(NodeInclusionPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.MatchLabelKeys != nil {
|
||||
in, out := &in.MatchLabelKeys, &out.MatchLabelKeys
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/apis/networking/register.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/networking/register.go
generated
vendored
@ -52,6 +52,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
&IngressList{},
|
||||
&IngressClass{},
|
||||
&IngressClassList{},
|
||||
&ClusterCIDR{},
|
||||
&ClusterCIDRList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
68
vendor/k8s.io/kubernetes/pkg/apis/networking/types.go
generated
vendored
68
vendor/k8s.io/kubernetes/pkg/apis/networking/types.go
generated
vendored
@ -154,8 +154,6 @@ type NetworkPolicyPort struct {
|
||||
// should be allowed by the policy. This field cannot be defined if the port field
|
||||
// is not defined or if the port field is defined as a named (string) port.
|
||||
// The endPort must be equal or greater than port.
|
||||
// This feature is in Beta state and is enabled by default.
|
||||
// It can be disabled using the Feature Gate "NetworkPolicyEndPort".
|
||||
// +optional
|
||||
EndPort *int32
|
||||
}
|
||||
@ -361,7 +359,7 @@ const (
|
||||
// IngressClassParametersReferenceScopeNamespace indicates that the
|
||||
// referenced Parameters resource is namespace-scoped.
|
||||
IngressClassParametersReferenceScopeNamespace = "Namespace"
|
||||
// IngressClassParametersReferenceScopeNamespace indicates that the
|
||||
// IngressClassParametersReferenceScopeCluster indicates that the
|
||||
// referenced Parameters resource is cluster-scoped.
|
||||
IngressClassParametersReferenceScopeCluster = "Cluster"
|
||||
)
|
||||
@ -585,3 +583,67 @@ type ServiceBackendPort struct {
|
||||
// +optional
|
||||
Number int32
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterCIDR represents a single configuration for per-Node Pod CIDR
|
||||
// allocations when the MultiCIDRRangeAllocator is enabled (see the config for
|
||||
// kube-controller-manager). A cluster may have any number of ClusterCIDR
|
||||
// resources, all of which will be considered when allocating a CIDR for a
|
||||
// Node. A ClusterCIDR is eligible to be used for a given Node when the node
|
||||
// selector matches the node in question and has free CIDRs to allocate. In
|
||||
// case of multiple matching ClusterCIDR resources, the allocator will attempt
|
||||
// to break ties using internal heuristics, but any ClusterCIDR whose node
|
||||
// selector matches the Node may be used.
|
||||
type ClusterCIDR struct {
|
||||
metav1.TypeMeta
|
||||
metav1.ObjectMeta
|
||||
|
||||
Spec ClusterCIDRSpec
|
||||
}
|
||||
|
||||
// ClusterCIDRSpec defines the desired state of ClusterCIDR.
|
||||
type ClusterCIDRSpec struct {
|
||||
// NodeSelector defines which nodes the config is applicable to.
|
||||
// An empty or nil NodeSelector selects all nodes.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
NodeSelector *api.NodeSelector
|
||||
|
||||
// PerNodeHostBits defines the number of host bits to be configured per node.
|
||||
// A subnet mask determines how much of the address is used for network bits
|
||||
// and host bits. For example an IPv4 address of 192.168.0.0/24, splits the
|
||||
// address into 24 bits for the network portion and 8 bits for the host portion.
|
||||
// To allocate 256 IPs, set this field to 8 (a /24 mask for IPv4 or a /120 for IPv6).
|
||||
// Minimum value is 4 (16 IPs).
|
||||
// This field is immutable.
|
||||
// +required
|
||||
PerNodeHostBits int32
|
||||
|
||||
// IPv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8").
|
||||
// At least one of IPv4 and IPv6 must be specified.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
IPv4 string
|
||||
|
||||
// IPv6 defines an IPv6 IP block in CIDR notation(e.g. "fd12:3456:789a:1::/64").
|
||||
// At least one of IPv4 and IPv6 must be specified.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
IPv6 string
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterCIDRList contains a list of ClusterCIDRs.
|
||||
type ClusterCIDRList struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// +optional
|
||||
metav1.ListMeta
|
||||
|
||||
// Items is the list of ClusterCIDRs.
|
||||
Items []ClusterCIDR
|
||||
}
|
||||
|
81
vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go
generated
vendored
81
vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go
generated
vendored
@ -28,6 +28,87 @@ import (
|
||||
core "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterCIDR) DeepCopyInto(out *ClusterCIDR) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCIDR.
|
||||
func (in *ClusterCIDR) DeepCopy() *ClusterCIDR {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterCIDR)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterCIDR) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterCIDRList) DeepCopyInto(out *ClusterCIDRList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ClusterCIDR, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCIDRList.
|
||||
func (in *ClusterCIDRList) DeepCopy() *ClusterCIDRList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterCIDRList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterCIDRList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterCIDRSpec) DeepCopyInto(out *ClusterCIDRSpec) {
|
||||
*out = *in
|
||||
if in.NodeSelector != nil {
|
||||
in, out := &in.NodeSelector, &out.NodeSelector
|
||||
*out = new(core.NodeSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCIDRSpec.
|
||||
func (in *ClusterCIDRSpec) DeepCopy() *ClusterCIDRSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterCIDRSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) {
|
||||
*out = *in
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/policy/types.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/policy/types.go
generated
vendored
@ -214,7 +214,6 @@ type PodSecurityPolicySpec struct {
|
||||
AllowedFlexVolumes []AllowedFlexVolume
|
||||
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
||||
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
||||
// This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.
|
||||
// +optional
|
||||
AllowedCSIDrivers []AllowedCSIDriver
|
||||
// AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.
|
||||
|
Reference in New Issue
Block a user