mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: update kubernetes to 1.28.0 in main
updating kubernetes to 1.28.0 in the main repo. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
b2fdc269c3
commit
ff3e84ad67
7
vendor/k8s.io/kubernetes/pkg/api/service/warnings.go
generated
vendored
7
vendor/k8s.io/kubernetes/pkg/api/service/warnings.go
generated
vendored
@ -53,6 +53,13 @@ func GetWarningsForService(service, oldService *api.Service) []string {
|
||||
warnings = append(warnings, getWarningsForCIDR(field.NewPath("spec").Child("loadBalancerSourceRanges").Index(i), cidr)...)
|
||||
}
|
||||
|
||||
if service.Spec.Type == api.ServiceTypeExternalName && len(service.Spec.ExternalIPs) > 0 {
|
||||
warnings = append(warnings, fmt.Sprintf("spec.externalIPs is ignored when spec.type is %q", api.ServiceTypeExternalName))
|
||||
}
|
||||
if service.Spec.Type != api.ServiceTypeExternalName && service.Spec.ExternalName != "" {
|
||||
warnings = append(warnings, fmt.Sprintf("spec.externalName is ignored when spec.type is not %q", api.ServiceTypeExternalName))
|
||||
}
|
||||
|
||||
return warnings
|
||||
}
|
||||
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/OWNERS
generated
vendored
@ -2,7 +2,6 @@
|
||||
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
|
92
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
92
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
@ -44,6 +44,13 @@ const (
|
||||
JobNameLabel = labelPrefix + LegacyJobNameLabel
|
||||
// Controller UID is used for selectors and labels for jobs
|
||||
ControllerUidLabel = labelPrefix + LegacyControllerUidLabel
|
||||
// Annotation indicating the number of failures for the index corresponding
|
||||
// to the pod, which are counted towards the backoff limit.
|
||||
JobIndexFailureCountAnnotation = labelPrefix + "job-index-failure-count"
|
||||
// Annotation indicating the number of failures for the index corresponding
|
||||
// to the pod, which don't count towards the backoff limit, according to the
|
||||
// pod failure policy. When the annotation is absent zero is implied.
|
||||
JobIndexIgnoredFailureCountAnnotation = labelPrefix + "job-index-ignored-failure-count"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@ -119,6 +126,12 @@ const (
|
||||
// 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 - mark the
|
||||
// Job's index as failed to avoid restarts within this index. This action
|
||||
// can only be used when backoffLimitPerIndex is set.
|
||||
// This value is alpha-level.
|
||||
PodFailurePolicyActionFailIndex PodFailurePolicyAction = "FailIndex"
|
||||
|
||||
// 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.
|
||||
@ -138,6 +151,19 @@ const (
|
||||
PodFailurePolicyOnExitCodesOpNotIn PodFailurePolicyOnExitCodesOperator = "NotIn"
|
||||
)
|
||||
|
||||
// PodReplacementPolicy specifies the policy for creating pod replacements.
|
||||
// +enum
|
||||
type PodReplacementPolicy string
|
||||
|
||||
const (
|
||||
// TerminatingOrFailed means that we recreate pods
|
||||
// when they are terminating (has a metadata.deletionTimestamp) or failed.
|
||||
TerminatingOrFailed PodReplacementPolicy = "TerminatingOrFailed"
|
||||
//Failed means to wait until a previously created Pod is fully terminated (has phase
|
||||
//Failed or Succeeded) before creating a replacement Pod.
|
||||
Failed PodReplacementPolicy = "Failed"
|
||||
)
|
||||
|
||||
// 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,
|
||||
@ -195,6 +221,10 @@ type PodFailurePolicyRule struct {
|
||||
//
|
||||
// - FailJob: indicates that the pod's job is marked as Failed and all
|
||||
// running pods are terminated.
|
||||
// - FailIndex: indicates that the pod's index is marked as Failed and will
|
||||
// not be restarted.
|
||||
// This value is alpha-level. It can be used when the
|
||||
// `JobBackoffLimitPerIndex` feature gate is enabled (disabled by default).
|
||||
// - 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
|
||||
@ -251,8 +281,8 @@ type JobSpec struct {
|
||||
// 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).
|
||||
// This field is beta-level. It can be used when the `JobPodFailurePolicy`
|
||||
// feature gate is enabled (enabled by default).
|
||||
// +optional
|
||||
PodFailurePolicy *PodFailurePolicy
|
||||
|
||||
@ -269,6 +299,30 @@ type JobSpec struct {
|
||||
// +optional
|
||||
BackoffLimit *int32
|
||||
|
||||
// Specifies the limit for the number of retries within an
|
||||
// index before marking this index as failed. When enabled the number of
|
||||
// failures per index is kept in the pod's
|
||||
// batch.kubernetes.io/job-index-failure-count annotation. It can only
|
||||
// be set when Job's completionMode=Indexed, and the Pod's restart
|
||||
// policy is Never. The field is immutable.
|
||||
// This field is alpha-level. It can be used when the `JobBackoffLimitPerIndex`
|
||||
// feature gate is enabled (disabled by default).
|
||||
// +optional
|
||||
BackoffLimitPerIndex *int32
|
||||
|
||||
// Specifies the maximal number of failed indexes before marking the Job as
|
||||
// failed, when backoffLimitPerIndex is set. Once the number of failed
|
||||
// indexes exceeds this number the entire Job is marked as Failed and its
|
||||
// execution is terminated. When left as null the job continues execution of
|
||||
// all of its indexes and is marked with the `Complete` Job condition.
|
||||
// It can only be specified when backoffLimitPerIndex is set.
|
||||
// It can be null or up to completions. It is required and must be
|
||||
// less than or equal to 10^4 when is completions greater than 10^5.
|
||||
// This field is alpha-level. It can be used when the `JobBackoffLimitPerIndex`
|
||||
// feature gate is enabled (disabled by default).
|
||||
// +optional
|
||||
MaxFailedIndexes *int32
|
||||
|
||||
// TODO enabled it when https://github.com/kubernetes/kubernetes/issues/28486 has been fixed
|
||||
// Optional number of failed pods to retain.
|
||||
// +optional
|
||||
@ -340,6 +394,19 @@ type JobSpec struct {
|
||||
//
|
||||
// +optional
|
||||
Suspend *bool
|
||||
|
||||
// podReplacementPolicy specifies when to create replacement Pods.
|
||||
// Possible values are:
|
||||
// - TerminatingOrFailed means that we recreate pods
|
||||
// when they are terminating (has a metadata.deletionTimestamp) or failed.
|
||||
// - Failed means to wait until a previously created Pod is fully terminated (has phase
|
||||
// Failed or Succeeded) before creating a replacement Pod.
|
||||
//
|
||||
// When using podFailurePolicy, Failed is the the only allowed value.
|
||||
// TerminatingOrFailed and Failed are allowed values when podFailurePolicy is not in use.
|
||||
// This is an alpha field. Enable JobPodReplacementPolicy to be able to use this field.
|
||||
// +optional
|
||||
PodReplacementPolicy *PodReplacementPolicy
|
||||
}
|
||||
|
||||
// JobStatus represents the current state of a Job.
|
||||
@ -372,6 +439,14 @@ type JobStatus struct {
|
||||
// +optional
|
||||
Active int32
|
||||
|
||||
// The number of pods which are terminating (in phase Pending or Running
|
||||
// and have a deletionTimestamp).
|
||||
//
|
||||
// This field is alpha-level. The job controller populates the field when
|
||||
// the feature gate JobPodReplacementPolicy is enabled (disabled by default).
|
||||
// +optional
|
||||
Terminating *int32
|
||||
|
||||
// The number of active pods which have a Ready condition.
|
||||
//
|
||||
// This field is beta-level. The job controller populates the field when
|
||||
@ -397,6 +472,19 @@ type JobStatus struct {
|
||||
// +optional
|
||||
CompletedIndexes string
|
||||
|
||||
// FailedIndexes holds the failed indexes when backoffLimitPerIndex=true.
|
||||
// The indexes are represented in the text format analogous as for the
|
||||
// `completedIndexes` field, ie. they are kept as decimal integers
|
||||
// separated by commas. The numbers are listed in increasing order. Three or
|
||||
// more consecutive numbers are compressed and represented by the first and
|
||||
// last element of the series, separated by a hyphen.
|
||||
// For example, if the failed indexes are 1, 3, 4, 5 and 7, they are
|
||||
// represented as "1,3-5,7".
|
||||
// This field is alpha-level. It can be used when the `JobBackoffLimitPerIndex`
|
||||
// feature gate is enabled (disabled by default).
|
||||
// +optional
|
||||
FailedIndexes *string
|
||||
|
||||
// uncountedTerminatedPods holds the UIDs of Pods that have terminated but
|
||||
// the job controller hasn't yet accounted for in the status counters.
|
||||
//
|
||||
|
25
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
25
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
@ -267,6 +267,16 @@ func (in *JobSpec) DeepCopyInto(out *JobSpec) {
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.BackoffLimitPerIndex != nil {
|
||||
in, out := &in.BackoffLimitPerIndex, &out.BackoffLimitPerIndex
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.MaxFailedIndexes != nil {
|
||||
in, out := &in.MaxFailedIndexes, &out.MaxFailedIndexes
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(v1.LabelSelector)
|
||||
@ -293,6 +303,11 @@ func (in *JobSpec) DeepCopyInto(out *JobSpec) {
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.PodReplacementPolicy != nil {
|
||||
in, out := &in.PodReplacementPolicy, &out.PodReplacementPolicy
|
||||
*out = new(PodReplacementPolicy)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -324,11 +339,21 @@ func (in *JobStatus) DeepCopyInto(out *JobStatus) {
|
||||
in, out := &in.CompletionTime, &out.CompletionTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.Terminating != nil {
|
||||
in, out := &in.Terminating, &out.Terminating
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Ready != nil {
|
||||
in, out := &in.Ready, &out.Ready
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailedIndexes != nil {
|
||||
in, out := &in.FailedIndexes, &out.FailedIndexes
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.UncountedTerminatedPods != nil {
|
||||
in, out := &in.UncountedTerminatedPods, &out.UncountedTerminatedPods
|
||||
*out = new(UncountedTerminatedPods)
|
||||
|
57
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
57
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
@ -360,6 +360,28 @@ func ContainsAccessMode(modes []core.PersistentVolumeAccessMode, mode core.Persi
|
||||
return false
|
||||
}
|
||||
|
||||
func ClaimContainsAllocatedResources(pvc *core.PersistentVolumeClaim) bool {
|
||||
if pvc == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if pvc.Status.AllocatedResources != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ClaimContainsAllocatedResourceStatus(pvc *core.PersistentVolumeClaim) bool {
|
||||
if pvc == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if pvc.Status.AllocatedResourceStatuses != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -453,41 +475,6 @@ func PersistentVolumeClaimHasClass(claim *core.PersistentVolumeClaim) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func toResourceNames(resources core.ResourceList) []core.ResourceName {
|
||||
result := []core.ResourceName{}
|
||||
for resourceName := range resources {
|
||||
result = append(result, resourceName)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toSet(resourceNames []core.ResourceName) sets.String {
|
||||
result := sets.NewString()
|
||||
for _, resourceName := range resourceNames {
|
||||
result.Insert(string(resourceName))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// toContainerResourcesSet returns a set of resources names in container resource requirements
|
||||
func toContainerResourcesSet(ctr *core.Container) sets.String {
|
||||
resourceNames := toResourceNames(ctr.Resources.Requests)
|
||||
resourceNames = append(resourceNames, toResourceNames(ctr.Resources.Limits)...)
|
||||
return toSet(resourceNames)
|
||||
}
|
||||
|
||||
// ToPodResourcesSet returns a set of resource names in all containers in a pod.
|
||||
func ToPodResourcesSet(podSpec *core.PodSpec) sets.String {
|
||||
result := sets.NewString()
|
||||
for i := range podSpec.InitContainers {
|
||||
result = result.Union(toContainerResourcesSet(&podSpec.InitContainers[i]))
|
||||
}
|
||||
for i := range podSpec.Containers {
|
||||
result = result.Union(toContainerResourcesSet(&podSpec.Containers[i]))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// GetDeletionCostFromPodAnnotations returns the integer value of pod-deletion-cost. Returns 0
|
||||
// if not set or the value is invalid.
|
||||
func GetDeletionCostFromPodAnnotations(annotations map[string]string) (int32, error) {
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/install/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/install/OWNERS
generated
vendored
@ -1,7 +1,6 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
reviewers:
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- deads2k
|
||||
- caesarxuchao
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/pods/helpers.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/pods/helpers.go
generated
vendored
@ -84,6 +84,7 @@ func ConvertDownwardAPIFieldLabel(version, label, value string) (string, string,
|
||||
"spec.schedulerName",
|
||||
"status.phase",
|
||||
"status.hostIP",
|
||||
"status.hostIPs",
|
||||
"status.podIP",
|
||||
"status.podIPs":
|
||||
return label, value, nil
|
||||
|
218
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
218
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
@ -380,6 +380,12 @@ type PersistentVolumeStatus struct {
|
||||
// Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI
|
||||
// +optional
|
||||
Reason string
|
||||
// LastPhaseTransitionTime is the time the phase transitioned from one to another
|
||||
// and automatically resets to current time everytime a volume phase transitions.
|
||||
// This is an alpha field and requires enabling PersistentVolumeLastPhaseTransitionTime feature.
|
||||
// +featureGate=PersistentVolumeLastPhaseTransitionTime
|
||||
// +optional
|
||||
LastPhaseTransitionTime *metav1.Time
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@ -515,23 +521,27 @@ const (
|
||||
)
|
||||
|
||||
// +enum
|
||||
type PersistentVolumeClaimResizeStatus string
|
||||
// When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
|
||||
// that it does not recognizes, then it should ignore that update and let other controllers
|
||||
// handle it.
|
||||
type ClaimResourceStatus string
|
||||
|
||||
const (
|
||||
// When expansion is complete, the empty string is set by resize controller or kubelet.
|
||||
PersistentVolumeClaimNoExpansionInProgress PersistentVolumeClaimResizeStatus = ""
|
||||
// State set when resize controller starts expanding the volume in control-plane
|
||||
PersistentVolumeClaimControllerExpansionInProgress PersistentVolumeClaimResizeStatus = "ControllerExpansionInProgress"
|
||||
// State set when expansion has failed in resize controller with a terminal error.
|
||||
// Transient errors such as timeout should not set this status and should leave ResizeStatus
|
||||
// State set when resize controller starts resizing the volume in control-plane
|
||||
PersistentVolumeClaimControllerResizeInProgress ClaimResourceStatus = "ControllerResizeInProgress"
|
||||
|
||||
// State set when resize has failed in resize controller with a terminal error.
|
||||
// Transient errors such as timeout should not set this status and should leave allocatedResourceStatus
|
||||
// unmodified, so as resize controller can resume the volume expansion.
|
||||
PersistentVolumeClaimControllerExpansionFailed PersistentVolumeClaimResizeStatus = "ControllerExpansionFailed"
|
||||
// State set when resize controller has finished expanding the volume but further expansion is needed on the node.
|
||||
PersistentVolumeClaimNodeExpansionPending PersistentVolumeClaimResizeStatus = "NodeExpansionPending"
|
||||
// State set when kubelet starts expanding the volume.
|
||||
PersistentVolumeClaimNodeExpansionInProgress PersistentVolumeClaimResizeStatus = "NodeExpansionInProgress"
|
||||
// State set when expansion has failed in kubelet with a terminal error. Transient errors don't set NodeExpansionFailed.
|
||||
PersistentVolumeClaimNodeExpansionFailed PersistentVolumeClaimResizeStatus = "NodeExpansionFailed"
|
||||
PersistentVolumeClaimControllerResizeFailed ClaimResourceStatus = "ControllerResizeFailed"
|
||||
|
||||
// State set when resize controller has finished resizing the volume but further resizing of volume
|
||||
// is needed on the node.
|
||||
PersistentVolumeClaimNodeResizePending ClaimResourceStatus = "NodeResizePending"
|
||||
// State set when kubelet starts resizing the volume.
|
||||
PersistentVolumeClaimNodeResizeInProgress ClaimResourceStatus = "NodeResizeInProgress"
|
||||
// State set when resizing has failed in kubelet with a terminal error. Transient errors don't set NodeResizeFailed
|
||||
PersistentVolumeClaimNodeResizeFailed ClaimResourceStatus = "NodeResizeFailed"
|
||||
)
|
||||
|
||||
// PersistentVolumeClaimCondition represents the current condition of PV claim
|
||||
@ -561,24 +571,70 @@ type PersistentVolumeClaimStatus struct {
|
||||
Capacity ResourceList
|
||||
// +optional
|
||||
Conditions []PersistentVolumeClaimCondition
|
||||
// The storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
|
||||
// be larger than the actual capacity when a volume expansion operation is requested.
|
||||
// AllocatedResources tracks the resources allocated to a PVC including its capacity.
|
||||
// Key names follow standard Kubernetes label syntax. Valid values are either:
|
||||
// * Un-prefixed keys:
|
||||
// - storage - the capacity of the volume.
|
||||
// * Custom resources must use implementation-defined prefixed names such as "example.com/my-custom-resource"
|
||||
// Apart from above values - keys that are unprefixed or have kubernetes.io prefix are considered
|
||||
// reserved and hence may not be used.
|
||||
//
|
||||
// Capacity reported here may be larger than the actual capacity when a volume expansion operation
|
||||
// is requested.
|
||||
// For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
|
||||
// If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
|
||||
// If a volume expansion capacity request is lowered, allocatedResources is only
|
||||
// lowered if there are no expansion operations in progress and if the actual volume capacity
|
||||
// is equal or lower than the requested capacity.
|
||||
//
|
||||
// A controller that receives PVC update with previously unknown resourceName
|
||||
// should ignore the update for the purpose it was designed. For example - a controller that
|
||||
// only is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid
|
||||
// resources associated with PVC.
|
||||
//
|
||||
// This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
|
||||
// +featureGate=RecoverVolumeExpansionFailure
|
||||
// +optional
|
||||
AllocatedResources ResourceList
|
||||
// ResizeStatus stores status of resize operation.
|
||||
// ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
|
||||
// string by resize controller or kubelet.
|
||||
// AllocatedResourceStatuses stores status of resource being resized for the given PVC.
|
||||
// Key names follow standard Kubernetes label syntax. Valid values are either:
|
||||
// * Un-prefixed keys:
|
||||
// - storage - the capacity of the volume.
|
||||
// * Custom resources must use implementation-defined prefixed names such as "example.com/my-custom-resource"
|
||||
// Apart from above values - keys that are unprefixed or have kubernetes.io prefix are considered
|
||||
// reserved and hence may not be used.
|
||||
//
|
||||
// ClaimResourceStatus can be in any of following states:
|
||||
// - ControllerResizeInProgress:
|
||||
// State set when resize controller starts resizing the volume in control-plane.
|
||||
// - ControllerResizeFailed:
|
||||
// State set when resize has failed in resize controller with a terminal error.
|
||||
// - NodeResizePending:
|
||||
// State set when resize controller has finished resizing the volume but further resizing of
|
||||
// volume is needed on the node.
|
||||
// - NodeResizeInProgress:
|
||||
// State set when kubelet starts resizing the volume.
|
||||
// - NodeResizeFailed:
|
||||
// State set when resizing has failed in kubelet with a terminal error. Transient errors don't set
|
||||
// NodeResizeFailed.
|
||||
// For example: if expanding a PVC for more capacity - this field can be one of the following states:
|
||||
// - pvc.status.allocatedResourceStatus['storage'] = "ControllerResizeInProgress"
|
||||
// - pvc.status.allocatedResourceStatus['storage'] = "ControllerResizeFailed"
|
||||
// - pvc.status.allocatedResourceStatus['storage'] = "NodeResizePending"
|
||||
// - pvc.status.allocatedResourceStatus['storage'] = "NodeResizeInProgress"
|
||||
// - pvc.status.allocatedResourceStatus['storage'] = "NodeResizeFailed"
|
||||
// When this field is not set, it means that no resize operation is in progress for the given PVC.
|
||||
//
|
||||
// A controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus
|
||||
// should ignore the update for the purpose it was designed. For example - a controller that
|
||||
// only is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid
|
||||
// resources associated with PVC.
|
||||
//
|
||||
// This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
|
||||
// +featureGate=RecoverVolumeExpansionFailure
|
||||
// +mapType=granular
|
||||
// +optional
|
||||
ResizeStatus *PersistentVolumeClaimResizeStatus
|
||||
AllocatedResourceStatuses map[ResourceName]ClaimResourceStatus
|
||||
}
|
||||
|
||||
// PersistentVolumeAccessMode defines various access modes for PV.
|
||||
@ -2279,6 +2335,24 @@ type Container struct {
|
||||
// +featureGate=InPlacePodVerticalScaling
|
||||
// +optional
|
||||
ResizePolicy []ContainerResizePolicy
|
||||
// RestartPolicy defines the restart behavior of individual containers in a pod.
|
||||
// This field may only be set for init containers, and the only allowed value is "Always".
|
||||
// For non-init containers or when this field is not specified,
|
||||
// the restart behavior is defined by the Pod's restart policy and the container type.
|
||||
// Setting the RestartPolicy as "Always" for the init container will have the following effect:
|
||||
// this init container will be continually restarted on
|
||||
// exit until all regular containers have terminated. Once all regular
|
||||
// containers have completed, all init containers with restartPolicy "Always"
|
||||
// will be shut down. This lifecycle differs from normal init containers and
|
||||
// is often referred to as a "sidecar" container. Although this init
|
||||
// container still starts in the init container sequence, it does not wait
|
||||
// for the container to complete before proceeding to the next init
|
||||
// container. Instead, the next init container starts immediately after this
|
||||
// init container is started, or after any startupProbe has successfully
|
||||
// completed.
|
||||
// +featureGate=SidecarContainers
|
||||
// +optional
|
||||
RestartPolicy *ContainerRestartPolicy
|
||||
// +optional
|
||||
VolumeMounts []VolumeMount
|
||||
// volumeDevices is the list of block devices to be used by the container.
|
||||
@ -2597,6 +2671,14 @@ const (
|
||||
RestartPolicyNever RestartPolicy = "Never"
|
||||
)
|
||||
|
||||
// ContainerRestartPolicy is the restart policy for a single container.
|
||||
// This may only be set for init containers and only allowed value is "Always".
|
||||
type ContainerRestartPolicy string
|
||||
|
||||
const (
|
||||
ContainerRestartPolicyAlways ContainerRestartPolicy = "Always"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PodList is a list of Pods.
|
||||
@ -3184,15 +3266,9 @@ type ClaimSource struct {
|
||||
//
|
||||
// The template will be used to create a new ResourceClaim, which will
|
||||
// be bound to this pod. When this pod is deleted, the ResourceClaim
|
||||
// will also be deleted. The name of the ResourceClaim will be <pod
|
||||
// name>-<resource name>, where <resource name> is the
|
||||
// PodResourceClaim.Name. Pod validation will reject the pod if the
|
||||
// concatenated name is not valid for a ResourceClaim (e.g. too long).
|
||||
//
|
||||
// An existing ResourceClaim with that name that is not owned by the
|
||||
// pod will not be used for the pod to avoid using an unrelated
|
||||
// resource by mistake. Scheduling and pod startup are then blocked
|
||||
// until the unrelated ResourceClaim is removed.
|
||||
// will also be deleted. The pod name and resource name, along with a
|
||||
// generated component, will be used to form a unique name for the
|
||||
// ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses.
|
||||
//
|
||||
// This field is immutable and no changes will be made to the
|
||||
// corresponding ResourceClaim by the control plane after creating the
|
||||
@ -3200,6 +3276,22 @@ type ClaimSource struct {
|
||||
ResourceClaimTemplateName *string
|
||||
}
|
||||
|
||||
// PodResourceClaimStatus is stored in the PodStatus for each PodResourceClaim
|
||||
// which references a ResourceClaimTemplate. It stores the generated name for
|
||||
// the corresponding ResourceClaim.
|
||||
type PodResourceClaimStatus struct {
|
||||
// Name uniquely identifies this resource claim inside the pod.
|
||||
// This must match the name of an entry in pod.spec.resourceClaims,
|
||||
// which implies that the string must be a DNS_LABEL.
|
||||
Name string
|
||||
|
||||
// ResourceClaimName is the name of the ResourceClaim that was
|
||||
// generated for the Pod in the namespace of the Pod. It this is
|
||||
// unset, then generating a ResourceClaim was not necessary. The
|
||||
// pod.spec.resourceClaims entry can be ignored in this case.
|
||||
ResourceClaimName *string
|
||||
}
|
||||
|
||||
// OSName is the set of OS'es that can be used in OS.
|
||||
type OSName string
|
||||
|
||||
@ -3446,12 +3538,15 @@ type PodDNSConfigOption struct {
|
||||
Value *string
|
||||
}
|
||||
|
||||
// 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.
|
||||
// PodIP represents a single IP address allocated to the pod.
|
||||
type PodIP struct {
|
||||
// IP is the IP address assigned to the pod
|
||||
IP string
|
||||
}
|
||||
|
||||
// HostIP represents a single IP address allocated to the host.
|
||||
type HostIP struct {
|
||||
// IP is the IP address assigned to the host
|
||||
IP string
|
||||
}
|
||||
|
||||
@ -3505,6 +3600,13 @@ type EphemeralContainerCommon struct {
|
||||
// +featureGate=InPlacePodVerticalScaling
|
||||
// +optional
|
||||
ResizePolicy []ContainerResizePolicy
|
||||
// Restart policy for the container to manage the restart behavior of each
|
||||
// container within a pod.
|
||||
// This may only be set for init containers. You cannot set this field on
|
||||
// ephemeral containers.
|
||||
// +featureGate=SidecarContainers
|
||||
// +optional
|
||||
RestartPolicy *ContainerRestartPolicy
|
||||
// Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers.
|
||||
// +optional
|
||||
VolumeMounts []VolumeMount
|
||||
@ -3594,9 +3696,21 @@ type PodStatus struct {
|
||||
// give the resources on this node to a higher priority pod that is created after preemption.
|
||||
// +optional
|
||||
NominatedNodeName string
|
||||
|
||||
// HostIP holds the IP address of the host to which the pod is assigned. Empty if the pod has not started yet.
|
||||
// A pod can be assigned to a node that has a problem in kubelet which in turns mean that HostIP will
|
||||
// not be updated even if there is a node is assigned to pod
|
||||
// +optional
|
||||
HostIP string
|
||||
|
||||
// HostIPs holds the IP addresses allocated to the host. If this field is specified, the first entry must
|
||||
// match the hostIP field. This list is empty if the pod has not started yet.
|
||||
// A pod can be assigned to a node that has a problem in kubelet which in turns means that HostIPs will
|
||||
// not be updated even if there is a node is assigned to this pod.
|
||||
// match the hostIP field. This list is empty if no IPs have been allocated yet.
|
||||
// +optional
|
||||
HostIPs []HostIP
|
||||
|
||||
// PodIPs holds all of the known IP addresses allocated to the pod. Pods may be assigned AT MOST
|
||||
// one value for each of IPv4 and IPv6.
|
||||
// +optional
|
||||
@ -3628,6 +3742,11 @@ type PodStatus struct {
|
||||
// +featureGate=InPlacePodVerticalScaling
|
||||
// +optional
|
||||
Resize PodResizeStatus
|
||||
|
||||
// Status of resource claims.
|
||||
// +featureGate=DynamicResourceAllocation
|
||||
// +optional
|
||||
ResourceClaimStatuses []PodResourceClaimStatus
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@ -4083,10 +4202,9 @@ type ServiceSpec struct {
|
||||
// This feature depends on whether the underlying cloud-provider supports specifying
|
||||
// the loadBalancerIP when a load balancer is created.
|
||||
// This field will be ignored if the cloud-provider does not support the feature.
|
||||
// Deprecated: This field was under-specified and its meaning varies across implementations,
|
||||
// and it cannot support dual-stack.
|
||||
// As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available.
|
||||
// This field may be removed in a future API version.
|
||||
// Deprecated: This field was under-specified and its meaning varies across implementations.
|
||||
// Using it is non-portable and it may not support dual-stack.
|
||||
// Users are encouraged to use implementation-specific annotations when available.
|
||||
// +optional
|
||||
LoadBalancerIP string
|
||||
|
||||
@ -4193,6 +4311,8 @@ type ServicePort struct {
|
||||
//
|
||||
// * Kubernetes-defined prefixed names:
|
||||
// * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540
|
||||
// * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455
|
||||
// * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455
|
||||
//
|
||||
// * Other protocols should use implementation-defined prefixed names such as
|
||||
// mycompany.com/my-custom-protocol.
|
||||
@ -4347,10 +4467,19 @@ type EndpointPort struct {
|
||||
Protocol Protocol
|
||||
|
||||
// The application protocol for this port.
|
||||
// This is used as a hint for implementations to offer richer behavior for protocols that they understand.
|
||||
// This field follows standard Kubernetes label syntax.
|
||||
// Un-prefixed names are reserved for IANA standard service names (as per
|
||||
// Valid values are either:
|
||||
//
|
||||
// * Un-prefixed protocol names - reserved for IANA standard service names (as per
|
||||
// RFC-6335 and https://www.iana.org/assignments/service-names).
|
||||
// Non-standard protocols should use prefixed names such as
|
||||
//
|
||||
// * Kubernetes-defined prefixed names:
|
||||
// * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540
|
||||
// * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455
|
||||
// * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455
|
||||
//
|
||||
// * Other protocols should use implementation-defined prefixed names such as
|
||||
// mycompany.com/my-custom-protocol.
|
||||
// +optional
|
||||
AppProtocol *string
|
||||
@ -5803,12 +5932,9 @@ type WindowsSecurityContextOptions struct {
|
||||
RunAsUserName *string
|
||||
|
||||
// HostProcess determines if a container should be run as a 'Host Process' container.
|
||||
// This field is alpha-level and will only be honored by components that enable the
|
||||
// WindowsHostProcessContainers feature flag. Setting this field without the feature
|
||||
// flag will result in errors when validating the Pod. All of a Pod's containers must
|
||||
// have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
|
||||
// containers and non-HostProcess containers). In addition, if HostProcess is true
|
||||
// then HostNetwork must also be set to true.
|
||||
// All of a Pod's containers must have the same effective HostProcess value
|
||||
// (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
|
||||
// In addition, if HostProcess is true then HostNetwork must also be set to true.
|
||||
// +optional
|
||||
HostProcess *bool
|
||||
}
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/OWNERS
generated
vendored
@ -2,7 +2,6 @@
|
||||
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go
generated
vendored
@ -42,6 +42,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
"spec.restartPolicy",
|
||||
"spec.schedulerName",
|
||||
"spec.serviceAccountName",
|
||||
"spec.hostNetwork",
|
||||
"status.phase",
|
||||
"status.podIP",
|
||||
"status.podIPs",
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults.go
generated
vendored
@ -118,8 +118,8 @@ func SetDefaults_Service(obj *v1.Service) {
|
||||
if sp.Protocol == "" {
|
||||
sp.Protocol = v1.ProtocolTCP
|
||||
}
|
||||
if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") {
|
||||
sp.TargetPort = intstr.FromInt(int(sp.Port))
|
||||
if sp.TargetPort == intstr.FromInt32(0) || sp.TargetPort == intstr.FromString("") {
|
||||
sp.TargetPort = intstr.FromInt32(sp.Port)
|
||||
}
|
||||
}
|
||||
// Defaults ExternalTrafficPolicy field for NodePort / LoadBalancer service
|
||||
@ -199,6 +199,11 @@ func SetDefaults_Pod(obj *v1.Pod) {
|
||||
enableServiceLinks := v1.DefaultEnableServiceLinks
|
||||
obj.Spec.EnableServiceLinks = &enableServiceLinks
|
||||
}
|
||||
|
||||
if obj.Spec.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Spec.Containers)
|
||||
defaultHostNetworkPorts(&obj.Spec.InitContainers)
|
||||
}
|
||||
}
|
||||
func SetDefaults_PodSpec(obj *v1.PodSpec) {
|
||||
// New fields added here will break upgrade tests:
|
||||
@ -211,9 +216,11 @@ func SetDefaults_PodSpec(obj *v1.PodSpec) {
|
||||
if obj.RestartPolicy == "" {
|
||||
obj.RestartPolicy = v1.RestartPolicyAlways
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
defaultHostNetworkPorts(&obj.InitContainers)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.DefaultHostNetworkHostPortsInPodTemplates) {
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
defaultHostNetworkPorts(&obj.InitContainers)
|
||||
}
|
||||
}
|
||||
if obj.SecurityContext == nil {
|
||||
obj.SecurityContext = &v1.PodSecurityContext{}
|
||||
|
6
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
@ -315,12 +315,6 @@ func AddOrUpdateTolerationInPodSpec(spec *v1.PodSpec, toleration *v1.Toleration)
|
||||
return true
|
||||
}
|
||||
|
||||
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
||||
// Returns true if something was updated, false otherwise.
|
||||
func AddOrUpdateTolerationInPod(pod *v1.Pod, toleration *v1.Toleration) bool {
|
||||
return AddOrUpdateTolerationInPodSpec(&pod.Spec, toleration)
|
||||
}
|
||||
|
||||
// GetMatchingTolerations returns true and list of Tolerations matching all Taints if all are tolerated, or false otherwise.
|
||||
func GetMatchingTolerations(taints []v1.Taint, tolerations []v1.Toleration) (bool, []v1.Toleration) {
|
||||
if len(taints) == 0 {
|
||||
|
76
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
76
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
@ -732,6 +732,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.HostIP)(nil), (*core.HostIP)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_HostIP_To_core_HostIP(a.(*v1.HostIP), b.(*core.HostIP), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.HostIP)(nil), (*v1.HostIP)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_HostIP_To_v1_HostIP(a.(*core.HostIP), b.(*v1.HostIP), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.HostPathVolumeSource)(nil), (*core.HostPathVolumeSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_HostPathVolumeSource_To_core_HostPathVolumeSource(a.(*v1.HostPathVolumeSource), b.(*core.HostPathVolumeSource), scope)
|
||||
}); err != nil {
|
||||
@ -1382,6 +1392,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.PodResourceClaimStatus)(nil), (*core.PodResourceClaimStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_PodResourceClaimStatus_To_core_PodResourceClaimStatus(a.(*v1.PodResourceClaimStatus), b.(*core.PodResourceClaimStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.PodResourceClaimStatus)(nil), (*v1.PodResourceClaimStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_PodResourceClaimStatus_To_v1_PodResourceClaimStatus(a.(*core.PodResourceClaimStatus), b.(*v1.PodResourceClaimStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.PodSchedulingGate)(nil), (*core.PodSchedulingGate)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_PodSchedulingGate_To_core_PodSchedulingGate(a.(*v1.PodSchedulingGate), b.(*core.PodSchedulingGate), scope)
|
||||
}); err != nil {
|
||||
@ -2986,6 +3006,7 @@ func autoConvert_v1_Container_To_core_Container(in *v1.Container, out *core.Cont
|
||||
return err
|
||||
}
|
||||
out.ResizePolicy = *(*[]core.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy))
|
||||
out.RestartPolicy = (*core.ContainerRestartPolicy)(unsafe.Pointer(in.RestartPolicy))
|
||||
out.VolumeMounts = *(*[]core.VolumeMount)(unsafe.Pointer(&in.VolumeMounts))
|
||||
out.VolumeDevices = *(*[]core.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices))
|
||||
out.LivenessProbe = (*core.Probe)(unsafe.Pointer(in.LivenessProbe))
|
||||
@ -3020,6 +3041,7 @@ func autoConvert_core_Container_To_v1_Container(in *core.Container, out *v1.Cont
|
||||
return err
|
||||
}
|
||||
out.ResizePolicy = *(*[]v1.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy))
|
||||
out.RestartPolicy = (*v1.ContainerRestartPolicy)(unsafe.Pointer(in.RestartPolicy))
|
||||
out.VolumeMounts = *(*[]v1.VolumeMount)(unsafe.Pointer(&in.VolumeMounts))
|
||||
out.VolumeDevices = *(*[]v1.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices))
|
||||
out.LivenessProbe = (*v1.Probe)(unsafe.Pointer(in.LivenessProbe))
|
||||
@ -3602,6 +3624,7 @@ func autoConvert_v1_EphemeralContainerCommon_To_core_EphemeralContainerCommon(in
|
||||
return err
|
||||
}
|
||||
out.ResizePolicy = *(*[]core.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy))
|
||||
out.RestartPolicy = (*core.ContainerRestartPolicy)(unsafe.Pointer(in.RestartPolicy))
|
||||
out.VolumeMounts = *(*[]core.VolumeMount)(unsafe.Pointer(&in.VolumeMounts))
|
||||
out.VolumeDevices = *(*[]core.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices))
|
||||
out.LivenessProbe = (*core.Probe)(unsafe.Pointer(in.LivenessProbe))
|
||||
@ -3636,6 +3659,7 @@ func autoConvert_core_EphemeralContainerCommon_To_v1_EphemeralContainerCommon(in
|
||||
return err
|
||||
}
|
||||
out.ResizePolicy = *(*[]v1.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy))
|
||||
out.RestartPolicy = (*v1.ContainerRestartPolicy)(unsafe.Pointer(in.RestartPolicy))
|
||||
out.VolumeMounts = *(*[]v1.VolumeMount)(unsafe.Pointer(&in.VolumeMounts))
|
||||
out.VolumeDevices = *(*[]v1.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices))
|
||||
out.LivenessProbe = (*v1.Probe)(unsafe.Pointer(in.LivenessProbe))
|
||||
@ -4119,6 +4143,26 @@ func Convert_core_HostAlias_To_v1_HostAlias(in *core.HostAlias, out *v1.HostAlia
|
||||
return autoConvert_core_HostAlias_To_v1_HostAlias(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_HostIP_To_core_HostIP(in *v1.HostIP, out *core.HostIP, s conversion.Scope) error {
|
||||
out.IP = in.IP
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_HostIP_To_core_HostIP is an autogenerated conversion function.
|
||||
func Convert_v1_HostIP_To_core_HostIP(in *v1.HostIP, out *core.HostIP, s conversion.Scope) error {
|
||||
return autoConvert_v1_HostIP_To_core_HostIP(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_HostIP_To_v1_HostIP(in *core.HostIP, out *v1.HostIP, s conversion.Scope) error {
|
||||
out.IP = in.IP
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_HostIP_To_v1_HostIP is an autogenerated conversion function.
|
||||
func Convert_core_HostIP_To_v1_HostIP(in *core.HostIP, out *v1.HostIP, s conversion.Scope) error {
|
||||
return autoConvert_core_HostIP_To_v1_HostIP(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_HostPathVolumeSource_To_core_HostPathVolumeSource(in *v1.HostPathVolumeSource, out *core.HostPathVolumeSource, s conversion.Scope) error {
|
||||
out.Path = in.Path
|
||||
out.Type = (*core.HostPathType)(unsafe.Pointer(in.Type))
|
||||
@ -5318,7 +5362,7 @@ func autoConvert_v1_PersistentVolumeClaimStatus_To_core_PersistentVolumeClaimSta
|
||||
out.Capacity = *(*core.ResourceList)(unsafe.Pointer(&in.Capacity))
|
||||
out.Conditions = *(*[]core.PersistentVolumeClaimCondition)(unsafe.Pointer(&in.Conditions))
|
||||
out.AllocatedResources = *(*core.ResourceList)(unsafe.Pointer(&in.AllocatedResources))
|
||||
out.ResizeStatus = (*core.PersistentVolumeClaimResizeStatus)(unsafe.Pointer(in.ResizeStatus))
|
||||
out.AllocatedResourceStatuses = *(*map[core.ResourceName]core.ClaimResourceStatus)(unsafe.Pointer(&in.AllocatedResourceStatuses))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5333,7 +5377,7 @@ func autoConvert_core_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimSta
|
||||
out.Capacity = *(*v1.ResourceList)(unsafe.Pointer(&in.Capacity))
|
||||
out.Conditions = *(*[]v1.PersistentVolumeClaimCondition)(unsafe.Pointer(&in.Conditions))
|
||||
out.AllocatedResources = *(*v1.ResourceList)(unsafe.Pointer(&in.AllocatedResources))
|
||||
out.ResizeStatus = (*v1.PersistentVolumeClaimResizeStatus)(unsafe.Pointer(in.ResizeStatus))
|
||||
out.AllocatedResourceStatuses = *(*map[v1.ResourceName]v1.ClaimResourceStatus)(unsafe.Pointer(&in.AllocatedResourceStatuses))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5528,6 +5572,7 @@ func autoConvert_v1_PersistentVolumeStatus_To_core_PersistentVolumeStatus(in *v1
|
||||
out.Phase = core.PersistentVolumePhase(in.Phase)
|
||||
out.Message = in.Message
|
||||
out.Reason = in.Reason
|
||||
out.LastPhaseTransitionTime = (*metav1.Time)(unsafe.Pointer(in.LastPhaseTransitionTime))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5540,6 +5585,7 @@ func autoConvert_core_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in *co
|
||||
out.Phase = v1.PersistentVolumePhase(in.Phase)
|
||||
out.Message = in.Message
|
||||
out.Reason = in.Reason
|
||||
out.LastPhaseTransitionTime = (*metav1.Time)(unsafe.Pointer(in.LastPhaseTransitionTime))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6207,6 +6253,28 @@ func Convert_core_PodResourceClaim_To_v1_PodResourceClaim(in *core.PodResourceCl
|
||||
return autoConvert_core_PodResourceClaim_To_v1_PodResourceClaim(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_PodResourceClaimStatus_To_core_PodResourceClaimStatus(in *v1.PodResourceClaimStatus, out *core.PodResourceClaimStatus, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.ResourceClaimName = (*string)(unsafe.Pointer(in.ResourceClaimName))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_PodResourceClaimStatus_To_core_PodResourceClaimStatus is an autogenerated conversion function.
|
||||
func Convert_v1_PodResourceClaimStatus_To_core_PodResourceClaimStatus(in *v1.PodResourceClaimStatus, out *core.PodResourceClaimStatus, s conversion.Scope) error {
|
||||
return autoConvert_v1_PodResourceClaimStatus_To_core_PodResourceClaimStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_PodResourceClaimStatus_To_v1_PodResourceClaimStatus(in *core.PodResourceClaimStatus, out *v1.PodResourceClaimStatus, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.ResourceClaimName = (*string)(unsafe.Pointer(in.ResourceClaimName))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_PodResourceClaimStatus_To_v1_PodResourceClaimStatus is an autogenerated conversion function.
|
||||
func Convert_core_PodResourceClaimStatus_To_v1_PodResourceClaimStatus(in *core.PodResourceClaimStatus, out *v1.PodResourceClaimStatus, s conversion.Scope) error {
|
||||
return autoConvert_core_PodResourceClaimStatus_To_v1_PodResourceClaimStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_PodSchedulingGate_To_core_PodSchedulingGate(in *v1.PodSchedulingGate, out *core.PodSchedulingGate, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
return nil
|
||||
@ -6413,6 +6481,7 @@ func autoConvert_v1_PodStatus_To_core_PodStatus(in *v1.PodStatus, out *core.PodS
|
||||
out.Reason = in.Reason
|
||||
out.NominatedNodeName = in.NominatedNodeName
|
||||
out.HostIP = in.HostIP
|
||||
out.HostIPs = *(*[]core.HostIP)(unsafe.Pointer(&in.HostIPs))
|
||||
// WARNING: in.PodIP requires manual conversion: does not exist in peer-type
|
||||
out.PodIPs = *(*[]core.PodIP)(unsafe.Pointer(&in.PodIPs))
|
||||
out.StartTime = (*metav1.Time)(unsafe.Pointer(in.StartTime))
|
||||
@ -6421,6 +6490,7 @@ func autoConvert_v1_PodStatus_To_core_PodStatus(in *v1.PodStatus, out *core.PodS
|
||||
out.QOSClass = core.PodQOSClass(in.QOSClass)
|
||||
out.EphemeralContainerStatuses = *(*[]core.ContainerStatus)(unsafe.Pointer(&in.EphemeralContainerStatuses))
|
||||
out.Resize = core.PodResizeStatus(in.Resize)
|
||||
out.ResourceClaimStatuses = *(*[]core.PodResourceClaimStatus)(unsafe.Pointer(&in.ResourceClaimStatuses))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6431,6 +6501,7 @@ func autoConvert_core_PodStatus_To_v1_PodStatus(in *core.PodStatus, out *v1.PodS
|
||||
out.Reason = in.Reason
|
||||
out.NominatedNodeName = in.NominatedNodeName
|
||||
out.HostIP = in.HostIP
|
||||
out.HostIPs = *(*[]v1.HostIP)(unsafe.Pointer(&in.HostIPs))
|
||||
out.PodIPs = *(*[]v1.PodIP)(unsafe.Pointer(&in.PodIPs))
|
||||
out.StartTime = (*metav1.Time)(unsafe.Pointer(in.StartTime))
|
||||
out.QOSClass = v1.PodQOSClass(in.QOSClass)
|
||||
@ -6438,6 +6509,7 @@ func autoConvert_core_PodStatus_To_v1_PodStatus(in *core.PodStatus, out *v1.PodS
|
||||
out.ContainerStatuses = *(*[]v1.ContainerStatus)(unsafe.Pointer(&in.ContainerStatuses))
|
||||
out.EphemeralContainerStatuses = *(*[]v1.ContainerStatus)(unsafe.Pointer(&in.EphemeralContainerStatuses))
|
||||
out.Resize = v1.PodResizeStatus(in.Resize)
|
||||
out.ResourceClaimStatuses = *(*[]v1.PodResourceClaimStatus)(unsafe.Pointer(&in.ResourceClaimStatuses))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/validation/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/validation/OWNERS
generated
vendored
@ -2,7 +2,6 @@
|
||||
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
|
461
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
461
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
@ -1055,6 +1055,7 @@ func validateDownwardAPIVolumeFile(file *core.DownwardAPIVolumeFile, fldPath *fi
|
||||
if file.ResourceFieldRef != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "resource", "fieldRef and resourceFieldRef can not be specified simultaneously"))
|
||||
}
|
||||
allErrs = append(allErrs, validateDownwardAPIHostIPs(file.FieldRef, fldPath.Child("fieldRef"), opts)...)
|
||||
} else if file.ResourceFieldRef != nil {
|
||||
localValidContainerResourceFieldPathPrefixes := validContainerResourceFieldPathPrefixesWithDownwardAPIHugePages
|
||||
allErrs = append(allErrs, validateContainerResourceFieldSelector(file.ResourceFieldRef, &validContainerResourceFieldPathExpressions, &localValidContainerResourceFieldPathPrefixes, fldPath.Child("resourceFieldRef"), true)...)
|
||||
@ -2019,18 +2020,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
|
||||
// Allow to validate the label value of the label selector
|
||||
AllowInvalidLabelValueInSelector bool
|
||||
}
|
||||
|
||||
func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolumeClaim) PersistentVolumeClaimSpecValidationOptions {
|
||||
opts := PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
EnableRecoverFromExpansionFailure: utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure),
|
||||
EnableRetroactiveDefaultStorageClass: utilfeature.DefaultFeatureGate.Enabled(features.RetroactiveDefaultStorageClass),
|
||||
AllowInvalidLabelValueInSelector: false,
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
EnableRecoverFromExpansionFailure: utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure),
|
||||
AllowInvalidLabelValueInSelector: false,
|
||||
}
|
||||
if oldPvc == nil {
|
||||
// If there's no old PVC, use the options based solely on feature enablement
|
||||
@ -2048,6 +2046,11 @@ func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolum
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
|
||||
if helper.ClaimContainsAllocatedResources(oldPvc) ||
|
||||
helper.ClaimContainsAllocatedResourceStatus(oldPvc) {
|
||||
opts.EnableRecoverFromExpansionFailure = true
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
@ -2286,24 +2289,39 @@ func validateStorageClassUpgradeFromAnnotation(oldAnnotations, newAnnotations ma
|
||||
|
||||
// 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
|
||||
// 1. The new pvc's StorageClassName is not nil
|
||||
// 2. The old pvc's StorageClassName is nil
|
||||
// 3. 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 */
|
||||
return newScName != nil /* condition 1 */ &&
|
||||
oldScName == nil /* condition 2 */ &&
|
||||
(!oldAnnotationExist || *newScName == oldAnnotation) /* condition 3 */
|
||||
}
|
||||
|
||||
var resizeStatusSet = sets.NewString(string(core.PersistentVolumeClaimNoExpansionInProgress),
|
||||
string(core.PersistentVolumeClaimControllerExpansionInProgress),
|
||||
string(core.PersistentVolumeClaimControllerExpansionFailed),
|
||||
string(core.PersistentVolumeClaimNodeExpansionPending),
|
||||
string(core.PersistentVolumeClaimNodeExpansionInProgress),
|
||||
string(core.PersistentVolumeClaimNodeExpansionFailed))
|
||||
func validatePersistentVolumeClaimResourceKey(value string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, msg := range validation.IsQualifiedName(value) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, value, msg))
|
||||
}
|
||||
if len(allErrs) != 0 {
|
||||
return allErrs
|
||||
}
|
||||
// For native resource names such as - either unprefixed names or with kubernetes.io prefix,
|
||||
// only allowed value is storage
|
||||
if helper.IsNativeResource(core.ResourceName(value)) {
|
||||
if core.ResourceName(value) != core.ResourceStorage {
|
||||
return append(allErrs, field.NotSupported(fldPath, value, []string{string(core.ResourceStorage)}))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
var resizeStatusSet = sets.NewString(string(core.PersistentVolumeClaimControllerResizeInProgress),
|
||||
string(core.PersistentVolumeClaimControllerResizeFailed),
|
||||
string(core.PersistentVolumeClaimNodeResizePending),
|
||||
string(core.PersistentVolumeClaimNodeResizeInProgress),
|
||||
string(core.PersistentVolumeClaimNodeResizeFailed))
|
||||
|
||||
// ValidatePersistentVolumeClaimStatusUpdate validates an update to status of a PersistentVolumeClaim
|
||||
func ValidatePersistentVolumeClaimStatusUpdate(newPvc, oldPvc *core.PersistentVolumeClaim, validationOpts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||
@ -2320,19 +2338,26 @@ func ValidatePersistentVolumeClaimStatusUpdate(newPvc, oldPvc *core.PersistentVo
|
||||
allErrs = append(allErrs, validateBasicResource(qty, capPath.Key(string(r)))...)
|
||||
}
|
||||
if validationOpts.EnableRecoverFromExpansionFailure {
|
||||
resizeStatusPath := field.NewPath("status", "resizeStatus")
|
||||
if newPvc.Status.ResizeStatus != nil {
|
||||
resizeStatus := *newPvc.Status.ResizeStatus
|
||||
if !resizeStatusSet.Has(string(resizeStatus)) {
|
||||
allErrs = append(allErrs, field.NotSupported(resizeStatusPath, resizeStatus, resizeStatusSet.List()))
|
||||
resizeStatusPath := field.NewPath("status", "allocatedResourceStatus")
|
||||
if newPvc.Status.AllocatedResourceStatuses != nil {
|
||||
resizeStatus := newPvc.Status.AllocatedResourceStatuses
|
||||
for k, v := range resizeStatus {
|
||||
if errs := validatePersistentVolumeClaimResourceKey(k.String(), resizeStatusPath); len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
}
|
||||
if !resizeStatusSet.Has(string(v)) {
|
||||
allErrs = append(allErrs, field.NotSupported(resizeStatusPath, k, resizeStatusSet.List()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
allocPath := field.NewPath("status", "allocatedResources")
|
||||
for r, qty := range newPvc.Status.AllocatedResources {
|
||||
if r != core.ResourceStorage {
|
||||
allErrs = append(allErrs, field.NotSupported(allocPath, r, []string{string(core.ResourceStorage)}))
|
||||
if errs := validatePersistentVolumeClaimResourceKey(r.String(), allocPath); len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
continue
|
||||
}
|
||||
|
||||
if errs := validateBasicResource(qty, allocPath.Key(string(r))); len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
} else {
|
||||
@ -2408,8 +2433,10 @@ var validEnvDownwardAPIFieldPathExpressions = sets.NewString(
|
||||
"spec.nodeName",
|
||||
"spec.serviceAccountName",
|
||||
"status.hostIP",
|
||||
"status.hostIPs",
|
||||
"status.podIP",
|
||||
"status.podIPs")
|
||||
"status.podIPs",
|
||||
)
|
||||
|
||||
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "limits.ephemeral-storage", "requests.cpu", "requests.memory", "requests.ephemeral-storage")
|
||||
|
||||
@ -2430,6 +2457,7 @@ func validateEnvVarValueFrom(ev core.EnvVar, fldPath *field.Path, opts PodValida
|
||||
if ev.ValueFrom.FieldRef != nil {
|
||||
numSources++
|
||||
allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldRef, &validEnvDownwardAPIFieldPathExpressions, fldPath.Child("fieldRef"))...)
|
||||
allErrs = append(allErrs, validateDownwardAPIHostIPs(ev.ValueFrom.FieldRef, fldPath.Child("fieldRef"), opts)...)
|
||||
}
|
||||
if ev.ValueFrom.ResourceFieldRef != nil {
|
||||
numSources++
|
||||
@ -2493,6 +2521,16 @@ func validateObjectFieldSelector(fs *core.ObjectFieldSelector, expressions *sets
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateDownwardAPIHostIPs(fieldSel *core.ObjectFieldSelector, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if !opts.AllowHostIPsField {
|
||||
if fieldSel.FieldPath == "status.hostIPs" {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, "may not be set when feature gate 'PodHostIPs' is not enabled"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateContainerResourceFieldSelector(fs *core.ResourceFieldSelector, expressions *sets.String, prefixes *sets.String, fldPath *field.Path, volume bool) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@ -2821,6 +2859,45 @@ func validatePodResourceClaimSource(claimSource core.ClaimSource, fldPath *field
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateLivenessProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(probe, fldPath)...)
|
||||
if probe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateReadinessProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(probe, fldPath)...)
|
||||
if probe.TerminationGracePeriodSeconds != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("terminationGracePeriodSeconds"), probe.TerminationGracePeriodSeconds, "must not be set for readinessProbes"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateStartupProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(probe, fldPath)...)
|
||||
if probe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@ -2840,6 +2917,23 @@ func validateProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateInitContainerRestartPolicy(restartPolicy *core.ContainerRestartPolicy, fldPath *field.Path) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
|
||||
if restartPolicy == nil {
|
||||
return allErrors
|
||||
}
|
||||
switch *restartPolicy {
|
||||
case core.ContainerRestartPolicyAlways:
|
||||
break
|
||||
default:
|
||||
validValues := []string{string(core.ContainerRestartPolicyAlways)}
|
||||
allErrors = append(allErrors, field.NotSupported(fldPath, *restartPolicy, validValues))
|
||||
}
|
||||
|
||||
return allErrors
|
||||
}
|
||||
|
||||
type commonHandler struct {
|
||||
Exec *core.ExecAction
|
||||
HTTPGet *core.HTTPGetAction
|
||||
@ -2970,7 +3064,7 @@ func validateTCPSocketAction(tcp *core.TCPSocketAction, fldPath *field.Path) fie
|
||||
return ValidatePortNumOrName(tcp.Port, fldPath.Child("port"))
|
||||
}
|
||||
func validateGRPCAction(grpc *core.GRPCAction, fldPath *field.Path) field.ErrorList {
|
||||
return ValidatePortNumOrName(intstr.FromInt(int(grpc.Port)), fldPath.Child("port"))
|
||||
return ValidatePortNumOrName(intstr.FromInt32(grpc.Port), fldPath.Child("port"))
|
||||
}
|
||||
func validateHandler(handler commonHandler, fldPath *field.Path) field.ErrorList {
|
||||
numHandlers := 0
|
||||
@ -3170,6 +3264,13 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
|
||||
// Apply the validation common to all container types
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, podClaimNames, idxPath, opts)...)
|
||||
|
||||
restartAlways := false
|
||||
// Apply the validation specific to init containers
|
||||
if ctr.RestartPolicy != nil {
|
||||
allErrs = append(allErrs, validateInitContainerRestartPolicy(ctr.RestartPolicy, idxPath.Child("restartPolicy"))...)
|
||||
restartAlways = *ctr.RestartPolicy == core.ContainerRestartPolicyAlways
|
||||
}
|
||||
|
||||
// Names must be unique within regular and init containers. Collisions with ephemeral containers
|
||||
// will be detected by validateEphemeralContainers().
|
||||
if allNames.Has(ctr.Name) {
|
||||
@ -3181,19 +3282,31 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
|
||||
// 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.Forbidden(idxPath.Child("lifecycle"), "may not be set for init containers"))
|
||||
}
|
||||
if ctr.LivenessProbe != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("livenessProbe"), "may not be set for init containers"))
|
||||
}
|
||||
if ctr.ReadinessProbe != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("readinessProbe"), "may not be set for init containers"))
|
||||
}
|
||||
if ctr.StartupProbe != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("startupProbe"), "may not be set for init containers"))
|
||||
switch {
|
||||
case restartAlways:
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, idxPath.Child("lifecycle"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, idxPath.Child("livenessProbe"))...)
|
||||
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, idxPath.Child("readinessProbe"))...)
|
||||
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
|
||||
|
||||
default:
|
||||
// These fields are disallowed for init containers.
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("lifecycle"), "may not be set for init containers without restartPolicy=Always"))
|
||||
}
|
||||
if ctr.LivenessProbe != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("livenessProbe"), "may not be set for init containers without restartPolicy=Always"))
|
||||
}
|
||||
if ctr.ReadinessProbe != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("readinessProbe"), "may not be set for init containers without restartPolicy=Always"))
|
||||
}
|
||||
if ctr.StartupProbe != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(idxPath.Child("startupProbe"), "may not be set for init containers without restartPolicy=Always"))
|
||||
}
|
||||
}
|
||||
|
||||
if len(ctr.ResizePolicy) > 0 {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("resizePolicy"), ctr.ResizePolicy, "must not be set for init containers"))
|
||||
}
|
||||
@ -3256,25 +3369,6 @@ func validateHostUsers(spec *core.PodSpec, fldPath *field.Path) field.ErrorList
|
||||
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
|
||||
@ -3318,22 +3412,20 @@ func validateContainers(containers []core.Container, volumes map[string]core.Vol
|
||||
allNames.Insert(ctr.Name)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// These fields are allowed for regular containers and restartable init
|
||||
// containers.
|
||||
// Regular init container and ephemeral container validation will return
|
||||
// field.Forbidden() for these paths.
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, path.Child("lifecycle"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.LivenessProbe, path.Child("livenessProbe"))...)
|
||||
if ctr.LivenessProbe != nil && ctr.LivenessProbe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(path.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
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(path.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
|
||||
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, path.Child("livenessProbe"))...)
|
||||
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, path.Child("readinessProbe"))...)
|
||||
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, path.Child("startupProbe"))...)
|
||||
|
||||
// These fields are disallowed for regular containers
|
||||
if ctr.RestartPolicy != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(path.Child("restartPolicy"), "may not be set for non-init containers"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -3399,14 +3491,10 @@ const (
|
||||
// restrictions in Linux libc name resolution handling.
|
||||
// Max number of DNS name servers.
|
||||
MaxDNSNameservers = 3
|
||||
// Expanded max number of domains in the search path list.
|
||||
MaxDNSSearchPathsExpanded = 32
|
||||
// Expanded max number of characters in the search path.
|
||||
MaxDNSSearchListCharsExpanded = 2048
|
||||
// Max number of domains in the search path list.
|
||||
MaxDNSSearchPathsLegacy = 6
|
||||
// Max number of characters in the search path list.
|
||||
MaxDNSSearchListCharsLegacy = 256
|
||||
MaxDNSSearchPaths = 32
|
||||
// Max number of characters in the search path.
|
||||
MaxDNSSearchListChars = 2048
|
||||
)
|
||||
|
||||
func validateReadinessGates(readinessGates []core.PodReadinessGate, fldPath *field.Path) field.ErrorList {
|
||||
@ -3455,16 +3543,12 @@ func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolic
|
||||
}
|
||||
}
|
||||
// Validate searches.
|
||||
maxDNSSearchPaths, maxDNSSearchListChars := MaxDNSSearchPathsLegacy, MaxDNSSearchListCharsLegacy
|
||||
if opts.AllowExpandedDNSConfig {
|
||||
maxDNSSearchPaths, maxDNSSearchListChars = MaxDNSSearchPathsExpanded, MaxDNSSearchListCharsExpanded
|
||||
}
|
||||
if len(dnsConfig.Searches) > maxDNSSearchPaths {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v search paths", maxDNSSearchPaths)))
|
||||
if len(dnsConfig.Searches) > MaxDNSSearchPaths {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v search paths", MaxDNSSearchPaths)))
|
||||
}
|
||||
// Include the space between search paths.
|
||||
if len(strings.Join(dnsConfig.Searches, " ")) > maxDNSSearchListChars {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v characters (including spaces) in the search list", maxDNSSearchListChars)))
|
||||
if len(strings.Join(dnsConfig.Searches, " ")) > MaxDNSSearchListChars {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v characters (including spaces) in the search list", MaxDNSSearchListChars)))
|
||||
}
|
||||
for i, search := range dnsConfig.Searches {
|
||||
// it is fine to have a trailing dot
|
||||
@ -3481,15 +3565,35 @@ func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolic
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateHostNetwork(hostNetwork bool, containers []core.Container, fldPath *field.Path) field.ErrorList {
|
||||
// validatePodHostNetworkDeps checks fields which depend on whether HostNetwork is
|
||||
// true or not. It should be called on all PodSpecs, but opts can change what
|
||||
// is enforce. E.g. opts.ResourceIsPod should only be set when called in the
|
||||
// context of a Pod, and not on PodSpecs which are embedded in other resources
|
||||
// (e.g. Deployments).
|
||||
func validatePodHostNetworkDeps(spec *core.PodSpec, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
// For <reasons> we keep `.HostNetwork` in .SecurityContext on the internal
|
||||
// version of Pod.
|
||||
hostNetwork := false
|
||||
if spec.SecurityContext != nil {
|
||||
hostNetwork = spec.SecurityContext.HostNetwork
|
||||
}
|
||||
|
||||
allErrors := field.ErrorList{}
|
||||
|
||||
if hostNetwork {
|
||||
for i, container := range containers {
|
||||
fldPath := fldPath.Child("containers")
|
||||
for i, container := range spec.Containers {
|
||||
portsPath := fldPath.Index(i).Child("ports")
|
||||
for i, port := range container.Ports {
|
||||
idxPath := portsPath.Index(i)
|
||||
if port.HostPort != port.ContainerPort {
|
||||
allErrors = append(allErrors, field.Invalid(idxPath.Child("containerPort"), port.ContainerPort, "must match `hostPort` when `hostNetwork` is true"))
|
||||
// At this point, we know that HostNetwork is true. If this
|
||||
// PodSpec is in a Pod (opts.ResourceIsPod), then HostPort must
|
||||
// be the same value as ContainerPort. If this PodSpec is in
|
||||
// some other resource (e.g. Deployment) we allow 0 (i.e.
|
||||
// unspecified) because it will be defaulted when the Pod is
|
||||
// ultimately created, but we do not allow any other values.
|
||||
if hp, cp := port.HostPort, port.ContainerPort; (opts.ResourceIsPod || hp != 0) && hp != cp {
|
||||
allErrors = append(allErrors, field.Invalid(idxPath.Child("hostPort"), port.HostPort, "must match `containerPort` when `hostNetwork` is true"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3688,25 +3792,29 @@ type PodValidationOptions struct {
|
||||
AllowInvalidLabelValueInSelector bool
|
||||
// Allow pod spec to use non-integer multiple of huge page unit size
|
||||
AllowIndivisibleHugePagesValues bool
|
||||
// Allow more DNSSearchPaths and longer DNSSearchListChars
|
||||
AllowExpandedDNSConfig bool
|
||||
// Allow pod spec to use status.hostIPs in downward API if feature is enabled
|
||||
AllowHostIPsField bool
|
||||
// Allow invalid topologySpreadConstraint labelSelector for backward compatibility
|
||||
AllowInvalidTopologySpreadConstraintLabelSelector bool
|
||||
// Allow node selector additions for gated pods.
|
||||
AllowMutableNodeSelectorAndNodeAffinity bool
|
||||
// The top-level resource being validated is a Pod, not just a PodSpec
|
||||
// embedded in some other resource.
|
||||
ResourceIsPod bool
|
||||
}
|
||||
|
||||
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
|
||||
// and is called by ValidatePodCreate and ValidatePodUpdate.
|
||||
func validatePodMetadataAndSpec(pod *core.Pod, opts PodValidationOptions) field.ErrorList {
|
||||
fldPath := field.NewPath("metadata")
|
||||
allErrs := ValidateObjectMeta(&pod.ObjectMeta, true, ValidatePodName, fldPath)
|
||||
allErrs = append(allErrs, ValidatePodSpecificAnnotations(pod.ObjectMeta.Annotations, &pod.Spec, fldPath.Child("annotations"), opts)...)
|
||||
allErrs = append(allErrs, ValidatePodSpec(&pod.Spec, &pod.ObjectMeta, field.NewPath("spec"), opts)...)
|
||||
metaPath := field.NewPath("metadata")
|
||||
specPath := field.NewPath("spec")
|
||||
|
||||
allErrs := ValidateObjectMeta(&pod.ObjectMeta, true, ValidatePodName, metaPath)
|
||||
allErrs = append(allErrs, ValidatePodSpecificAnnotations(pod.ObjectMeta.Annotations, &pod.Spec, metaPath.Child("annotations"), opts)...)
|
||||
allErrs = append(allErrs, ValidatePodSpec(&pod.Spec, &pod.ObjectMeta, specPath, opts)...)
|
||||
|
||||
// we do additional validation only pertinent for pods and not pod templates
|
||||
// this was done to preserve backwards compatibility
|
||||
specPath := field.NewPath("spec")
|
||||
|
||||
if pod.Spec.ServiceAccountName == "" {
|
||||
for vi, volume := range pod.Spec.Volumes {
|
||||
@ -3774,6 +3882,58 @@ func validatePodIPs(pod *core.Pod) field.ErrorList {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateHostIPs validates IPs in pod status
|
||||
func validateHostIPs(pod *core.Pod) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(pod.Status.HostIPs) == 0 {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
hostIPsField := field.NewPath("status", "hostIPs")
|
||||
|
||||
// hostIP must be equal to hostIPs[0].IP
|
||||
if pod.Status.HostIP != pod.Status.HostIPs[0].IP {
|
||||
allErrs = append(allErrs, field.Invalid(hostIPsField.Index(0).Child("ip"), pod.Status.HostIPs[0].IP, "must be equal to `hostIP`"))
|
||||
}
|
||||
|
||||
// all HostPs must be valid IPs
|
||||
for i, hostIP := range pod.Status.HostIPs {
|
||||
for _, msg := range validation.IsValidIP(hostIP.IP) {
|
||||
allErrs = append(allErrs, field.Invalid(hostIPsField.Index(i), hostIP.IP, msg))
|
||||
}
|
||||
}
|
||||
|
||||
// if we have more than one Pod.HostIP then
|
||||
// - validate for dual stack
|
||||
// - validate for duplication
|
||||
if len(pod.Status.HostIPs) > 1 {
|
||||
seen := sets.String{}
|
||||
hostIPs := make([]string, 0, len(pod.Status.HostIPs))
|
||||
|
||||
// There should be no duplicates in list of Pod.HostIPs
|
||||
for i, hostIP := range pod.Status.HostIPs {
|
||||
hostIPs = append(hostIPs, hostIP.IP)
|
||||
if seen.Has(hostIP.IP) {
|
||||
allErrs = append(allErrs, field.Duplicate(hostIPsField.Index(i), hostIP))
|
||||
}
|
||||
seen.Insert(hostIP.IP)
|
||||
}
|
||||
|
||||
dualStack, err := netutils.IsDualStackIPStrings(hostIPs)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.InternalError(hostIPsField, fmt.Errorf("failed to check for dual stack with error:%v", err)))
|
||||
}
|
||||
|
||||
// We only support one from each IP family (i.e. max two IPs in this list).
|
||||
if !dualStack || len(hostIPs) > 2 {
|
||||
allErrs = append(allErrs, field.Invalid(hostIPsField, pod.Status.HostIPs, "may specify no more than one IP for each IP family"))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodSpec tests that the specified PodSpec has valid data.
|
||||
// This includes checking formatting and uniqueness. It also canonicalizes the
|
||||
// structure by setting default values and implementing any backwards-compatibility
|
||||
@ -3790,10 +3950,11 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
|
||||
allErrs = append(allErrs, validateContainers(spec.Containers, vols, podClaimNames, fldPath.Child("containers"), opts)...)
|
||||
allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, podClaimNames, fldPath.Child("initContainers"), opts)...)
|
||||
allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, podClaimNames, fldPath.Child("ephemeralContainers"), opts)...)
|
||||
allErrs = append(allErrs, validatePodHostNetworkDeps(spec, fldPath, opts)...)
|
||||
allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy, fldPath.Child("restartPolicy"))...)
|
||||
allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy, fldPath.Child("dnsPolicy"))...)
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabels(spec.NodeSelector, fldPath.Child("nodeSelector"))...)
|
||||
allErrs = append(allErrs, ValidatePodSecurityContext(spec.SecurityContext, spec, fldPath, fldPath.Child("securityContext"), opts)...)
|
||||
allErrs = append(allErrs, validatePodSpecSecurityContext(spec.SecurityContext, spec, fldPath, fldPath.Child("securityContext"), opts)...)
|
||||
allErrs = append(allErrs, validateImagePullSecrets(spec.ImagePullSecrets, fldPath.Child("imagePullSecrets"))...)
|
||||
allErrs = append(allErrs, validateAffinity(spec.Affinity, opts, fldPath.Child("affinity"))...)
|
||||
allErrs = append(allErrs, validatePodDNSConfig(spec.DNSConfig, &spec.DNSPolicy, fldPath.Child("dnsConfig"), opts)...)
|
||||
@ -4396,12 +4557,13 @@ func validateSysctls(sysctls []core.Sysctl, fldPath *field.Path) field.ErrorList
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodSecurityContext test that the specified PodSecurityContext has valid data.
|
||||
func ValidatePodSecurityContext(securityContext *core.PodSecurityContext, spec *core.PodSpec, specPath, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
// validatePodSpecSecurityContext verifies the SecurityContext of a PodSpec,
|
||||
// whether that is defined in a Pod or in an embedded PodSpec (e.g. a
|
||||
// Deployment's pod template).
|
||||
func validatePodSpecSecurityContext(securityContext *core.PodSecurityContext, spec *core.PodSpec, specPath, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if securityContext != nil {
|
||||
allErrs = append(allErrs, validateHostNetwork(securityContext.HostNetwork, spec.Containers, specPath.Child("containers"))...)
|
||||
if securityContext.FSGroup != nil {
|
||||
for _, msg := range validation.IsValidGroupID(*securityContext.FSGroup) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("fsGroup"), *(securityContext.FSGroup), msg))
|
||||
@ -4802,11 +4964,16 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions
|
||||
allErrs = append(allErrs, ValidateContainerStateTransition(newPod.Status.InitContainerStatuses, oldPod.Status.InitContainerStatuses, fldPath.Child("initContainerStatuses"), oldPod.Spec.RestartPolicy)...)
|
||||
// The kubelet will never restart ephemeral containers, so treat them like they have an implicit RestartPolicyNever.
|
||||
allErrs = append(allErrs, ValidateContainerStateTransition(newPod.Status.EphemeralContainerStatuses, oldPod.Status.EphemeralContainerStatuses, fldPath.Child("ephemeralContainerStatuses"), core.RestartPolicyNever)...)
|
||||
allErrs = append(allErrs, validatePodResourceClaimStatuses(newPod.Status.ResourceClaimStatuses, newPod.Spec.ResourceClaims, fldPath.Child("resourceClaimStatuses"))...)
|
||||
|
||||
if newIPErrs := validatePodIPs(newPod); len(newIPErrs) > 0 {
|
||||
allErrs = append(allErrs, newIPErrs...)
|
||||
}
|
||||
|
||||
if newIPErrs := validateHostIPs(newPod); len(newIPErrs) > 0 {
|
||||
allErrs = append(allErrs, newIPErrs...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -4823,6 +4990,42 @@ func validatePodConditions(conditions []core.PodCondition, fldPath *field.Path)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validatePodResourceClaimStatuses validates the ResourceClaimStatuses slice in a pod status.
|
||||
func validatePodResourceClaimStatuses(statuses []core.PodResourceClaimStatus, podClaims []core.PodResourceClaim, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
claimNames := sets.New[string]()
|
||||
for i, status := range statuses {
|
||||
idxPath := fldPath.Index(i)
|
||||
// There's no need to check the content of the name. If it matches an entry,
|
||||
// then it is valid, otherwise we reject it here.
|
||||
if !havePodClaim(podClaims, status.Name) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), status.Name, "must match the name of an entry in `spec.resourceClaims`"))
|
||||
}
|
||||
if claimNames.Has(status.Name) {
|
||||
allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), status.Name))
|
||||
} else {
|
||||
claimNames.Insert(status.Name)
|
||||
}
|
||||
if status.ResourceClaimName != nil {
|
||||
for _, detail := range ValidateResourceClaimName(*status.ResourceClaimName, false) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), status.ResourceClaimName, detail))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func havePodClaim(podClaims []core.PodResourceClaim, name string) bool {
|
||||
for _, podClaim := range podClaims {
|
||||
if podClaim.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidatePodEphemeralContainersUpdate tests that a user update to EphemeralContainers is valid.
|
||||
// newPod and oldPod must only differ in their EphemeralContainers.
|
||||
func ValidatePodEphemeralContainersUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) field.ErrorList {
|
||||
@ -5245,14 +5448,14 @@ func ValidateServiceStatusUpdate(service, oldService *core.Service) field.ErrorL
|
||||
// ValidateReplicationController tests if required fields in the replication controller are set.
|
||||
func ValidateReplicationController(controller *core.ReplicationController, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := ValidateObjectMeta(&controller.ObjectMeta, true, ValidateReplicationControllerName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateReplicationControllerSpec(&controller.Spec, field.NewPath("spec"), opts)...)
|
||||
allErrs = append(allErrs, ValidateReplicationControllerSpec(&controller.Spec, nil, field.NewPath("spec"), opts)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateReplicationControllerUpdate tests if required fields in the replication controller are set.
|
||||
func ValidateReplicationControllerUpdate(controller, oldController *core.ReplicationController, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateReplicationControllerSpec(&controller.Spec, field.NewPath("spec"), opts)...)
|
||||
allErrs = append(allErrs, ValidateReplicationControllerSpec(&controller.Spec, &oldController.Spec, field.NewPath("spec"), opts)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -5297,7 +5500,7 @@ func ValidateNonEmptySelector(selectorMap map[string]string, fldPath *field.Path
|
||||
}
|
||||
|
||||
// Validates the given template and ensures that it is in accordance with the desired selector and replicas.
|
||||
func ValidatePodTemplateSpecForRC(template *core.PodTemplateSpec, selectorMap map[string]string, replicas int32, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
func ValidatePodTemplateSpecForRC(template, oldTemplate *core.PodTemplateSpec, selectorMap map[string]string, replicas int32, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if template == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath, ""))
|
||||
@ -5311,8 +5514,13 @@ func ValidatePodTemplateSpecForRC(template *core.PodTemplateSpec, selectorMap ma
|
||||
}
|
||||
}
|
||||
allErrs = append(allErrs, ValidatePodTemplateSpec(template, fldPath, opts)...)
|
||||
// get rid of apivalidation.ValidateReadOnlyPersistentDisks,stop passing oldTemplate to this function
|
||||
var oldVols []core.Volume
|
||||
if oldTemplate != nil {
|
||||
oldVols = oldTemplate.Spec.Volumes // +k8s:verify-mutation:reason=clone
|
||||
}
|
||||
if replicas > 1 {
|
||||
allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(template.Spec.Volumes, fldPath.Child("spec", "volumes"))...)
|
||||
allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(template.Spec.Volumes, oldVols, fldPath.Child("spec", "volumes"))...)
|
||||
}
|
||||
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
|
||||
if template.Spec.RestartPolicy != core.RestartPolicyAlways {
|
||||
@ -5326,12 +5534,17 @@ func ValidatePodTemplateSpecForRC(template *core.PodTemplateSpec, selectorMap ma
|
||||
}
|
||||
|
||||
// ValidateReplicationControllerSpec tests if required fields in the replication controller spec are set.
|
||||
func ValidateReplicationControllerSpec(spec *core.ReplicationControllerSpec, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
func ValidateReplicationControllerSpec(spec, oldSpec *core.ReplicationControllerSpec, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
|
||||
allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...)
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
|
||||
allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...)
|
||||
// oldSpec is not empty, pass oldSpec.template.
|
||||
var oldTemplate *core.PodTemplateSpec
|
||||
if oldSpec != nil {
|
||||
oldTemplate = oldSpec.Template // +k8s:verify-mutation:reason=clone
|
||||
}
|
||||
allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, oldTemplate, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -5351,17 +5564,29 @@ func ValidatePodTemplateSpec(spec *core.PodTemplateSpec, fldPath *field.Path, op
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateReadOnlyPersistentDisks(volumes []core.Volume, fldPath *field.Path) field.ErrorList {
|
||||
// ValidateReadOnlyPersistentDisks stick this AFTER the short-circuit checks
|
||||
func ValidateReadOnlyPersistentDisks(volumes, oldVolumes []core.Volume, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for i := range volumes {
|
||||
vol := &volumes[i]
|
||||
idxPath := fldPath.Index(i)
|
||||
if vol.GCEPersistentDisk != nil {
|
||||
if !vol.GCEPersistentDisk.ReadOnly {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("gcePersistentDisk", "readOnly"), false, "must be true for replicated pods > 1; GCE PD can only be mounted on multiple machines if it is read-only"))
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SkipReadOnlyValidationGCE) {
|
||||
return field.ErrorList{}
|
||||
}
|
||||
|
||||
isWriteablePD := func(vol *core.Volume) bool {
|
||||
return vol.GCEPersistentDisk != nil && !vol.GCEPersistentDisk.ReadOnly
|
||||
}
|
||||
|
||||
for i := range oldVolumes {
|
||||
if isWriteablePD(&oldVolumes[i]) {
|
||||
return field.ErrorList{}
|
||||
}
|
||||
}
|
||||
|
||||
for i := range volumes {
|
||||
idxPath := fldPath.Index(i)
|
||||
if isWriteablePD(&volumes[i]) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("gcePersistentDisk", "readOnly"), false, "must be true for replicated pods > 1; GCE PD can only be mounted on multiple machines if it is read-only"))
|
||||
}
|
||||
// TODO: What to do for AWS? It doesn't support replicas
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
75
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
75
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
@ -793,6 +793,11 @@ func (in *Container) DeepCopyInto(out *Container) {
|
||||
*out = make([]ContainerResizePolicy, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.RestartPolicy != nil {
|
||||
in, out := &in.RestartPolicy, &out.RestartPolicy
|
||||
*out = new(ContainerRestartPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.VolumeMounts != nil {
|
||||
in, out := &in.VolumeMounts, &out.VolumeMounts
|
||||
*out = make([]VolumeMount, len(*in))
|
||||
@ -1420,6 +1425,11 @@ func (in *EphemeralContainerCommon) DeepCopyInto(out *EphemeralContainerCommon)
|
||||
*out = make([]ContainerResizePolicy, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.RestartPolicy != nil {
|
||||
in, out := &in.RestartPolicy, &out.RestartPolicy
|
||||
*out = new(ContainerRestartPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.VolumeMounts != nil {
|
||||
in, out := &in.VolumeMounts, &out.VolumeMounts
|
||||
*out = make([]VolumeMount, len(*in))
|
||||
@ -1871,6 +1881,22 @@ func (in *HostAlias) DeepCopy() *HostAlias {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostIP) DeepCopyInto(out *HostIP) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostIP.
|
||||
func (in *HostIP) DeepCopy() *HostIP {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostIP)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostPathVolumeSource) DeepCopyInto(out *HostPathVolumeSource) {
|
||||
*out = *in
|
||||
@ -2897,7 +2923,7 @@ func (in *PersistentVolume) DeepCopyInto(out *PersistentVolume) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
@ -3074,10 +3100,12 @@ func (in *PersistentVolumeClaimStatus) DeepCopyInto(out *PersistentVolumeClaimSt
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.ResizeStatus != nil {
|
||||
in, out := &in.ResizeStatus, &out.ResizeStatus
|
||||
*out = new(PersistentVolumeClaimResizeStatus)
|
||||
**out = **in
|
||||
if in.AllocatedResourceStatuses != nil {
|
||||
in, out := &in.AllocatedResourceStatuses, &out.AllocatedResourceStatuses
|
||||
*out = make(map[ResourceName]ClaimResourceStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -3337,6 +3365,10 @@ func (in *PersistentVolumeSpec) DeepCopy() *PersistentVolumeSpec {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PersistentVolumeStatus) DeepCopyInto(out *PersistentVolumeStatus) {
|
||||
*out = *in
|
||||
if in.LastPhaseTransitionTime != nil {
|
||||
in, out := &in.LastPhaseTransitionTime, &out.LastPhaseTransitionTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -3809,6 +3841,27 @@ func (in *PodResourceClaim) DeepCopy() *PodResourceClaim {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodResourceClaimStatus) DeepCopyInto(out *PodResourceClaimStatus) {
|
||||
*out = *in
|
||||
if in.ResourceClaimName != nil {
|
||||
in, out := &in.ResourceClaimName, &out.ResourceClaimName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodResourceClaimStatus.
|
||||
func (in *PodResourceClaimStatus) DeepCopy() *PodResourceClaimStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodResourceClaimStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodSchedulingGate) DeepCopyInto(out *PodSchedulingGate) {
|
||||
*out = *in
|
||||
@ -4093,6 +4146,11 @@ func (in *PodStatus) DeepCopyInto(out *PodStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.HostIPs != nil {
|
||||
in, out := &in.HostIPs, &out.HostIPs
|
||||
*out = make([]HostIP, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.PodIPs != nil {
|
||||
in, out := &in.PodIPs, &out.PodIPs
|
||||
*out = make([]PodIP, len(*in))
|
||||
@ -4123,6 +4181,13 @@ func (in *PodStatus) DeepCopyInto(out *PodStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.ResourceClaimStatuses != nil {
|
||||
in, out := &in.ResourceClaimStatuses, &out.ResourceClaimStatuses
|
||||
*out = make([]PodResourceClaimStatus, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/apis/extensions/OWNERS
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/extensions/OWNERS
generated
vendored
@ -2,7 +2,6 @@
|
||||
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
@ -19,5 +18,6 @@ reviewers:
|
||||
- mwielgus
|
||||
- soltysh
|
||||
- dims
|
||||
- jpbetz
|
||||
labels:
|
||||
- sig/apps
|
||||
|
41
vendor/k8s.io/kubernetes/pkg/apis/networking/types.go
generated
vendored
41
vendor/k8s.io/kubernetes/pkg/apis/networking/types.go
generated
vendored
@ -35,11 +35,6 @@ type NetworkPolicy struct {
|
||||
// spec represents the specification of the desired behavior for this NetworkPolicy.
|
||||
// +optional
|
||||
Spec NetworkPolicySpec
|
||||
|
||||
// status represents the current state of the NetworkPolicy.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
Status NetworkPolicyStatus
|
||||
}
|
||||
|
||||
// PolicyType describes the NetworkPolicy type
|
||||
@ -201,42 +196,6 @@ type NetworkPolicyPeer struct {
|
||||
IPBlock *IPBlock
|
||||
}
|
||||
|
||||
// NetworkPolicyConditionType is the type for status conditions on
|
||||
// a NetworkPolicy. This type should be used with the
|
||||
// NetworkPolicyStatus.Conditions field.
|
||||
type NetworkPolicyConditionType string
|
||||
|
||||
const (
|
||||
// NetworkPolicyConditionStatusAccepted represents status of a Network Policy that could be properly parsed by
|
||||
// the Network Policy provider and will be implemented in the cluster
|
||||
NetworkPolicyConditionStatusAccepted NetworkPolicyConditionType = "Accepted"
|
||||
|
||||
// NetworkPolicyConditionStatusPartialFailure represents status of a Network Policy that could be partially
|
||||
// parsed by the Network Policy provider and may not be completely implemented due to a lack of a feature or some
|
||||
// other condition
|
||||
NetworkPolicyConditionStatusPartialFailure NetworkPolicyConditionType = "PartialFailure"
|
||||
|
||||
// NetworkPolicyConditionStatusFailure represents status of a Network Policy that could not be parsed by the
|
||||
// Network Policy provider and will not be implemented in the cluster
|
||||
NetworkPolicyConditionStatusFailure NetworkPolicyConditionType = "Failure"
|
||||
)
|
||||
|
||||
// NetworkPolicyConditionReason defines the set of reasons that explain why a
|
||||
// particular NetworkPolicy condition type has been raised.
|
||||
type NetworkPolicyConditionReason string
|
||||
|
||||
const (
|
||||
// NetworkPolicyConditionReasonFeatureNotSupported represents a reason where the Network Policy may not have been
|
||||
// implemented in the cluster due to a lack of some feature not supported by the Network Policy provider
|
||||
NetworkPolicyConditionReasonFeatureNotSupported NetworkPolicyConditionReason = "FeatureNotSupported"
|
||||
)
|
||||
|
||||
// NetworkPolicyStatus describes the current state of the NetworkPolicy.
|
||||
type NetworkPolicyStatus struct {
|
||||
// conditions holds an array of metav1.Condition that describes the state of the NetworkPolicy.
|
||||
Conditions []metav1.Condition
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// NetworkPolicyList is a list of NetworkPolicy objects.
|
||||
|
24
vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go
generated
vendored
24
vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go
generated
vendored
@ -661,7 +661,6 @@ func (in *NetworkPolicy) DeepCopyInto(out *NetworkPolicy) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
@ -874,29 +873,6 @@ func (in *NetworkPolicySpec) DeepCopy() *NetworkPolicySpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NetworkPolicyStatus) DeepCopyInto(out *NetworkPolicyStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyStatus.
|
||||
func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NetworkPolicyStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ParentReference) DeepCopyInto(out *ParentReference) {
|
||||
*out = *in
|
||||
|
12
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
@ -236,8 +236,8 @@ func (m *PodControllerRefManager) AdoptPod(ctx context.Context, pod *v1.Pod) err
|
||||
// ReleasePod sends a patch to free the pod from the control of the controller.
|
||||
// It returns the error if the patching fails. 404 and 422 errors are ignored.
|
||||
func (m *PodControllerRefManager) ReleasePod(ctx context.Context, pod *v1.Pod) error {
|
||||
klog.V(2).Infof("patching pod %s_%s to remove its controllerRef to %s/%s:%s",
|
||||
pod.Namespace, pod.Name, m.controllerKind.GroupVersion(), m.controllerKind.Kind, m.Controller.GetName())
|
||||
logger := klog.FromContext(ctx)
|
||||
logger.V(2).Info("Patching pod to remove its controllerRef", "pod", klog.KObj(pod), "gvk", m.controllerKind, "controller", m.Controller.GetName())
|
||||
patchBytes, err := GenerateDeleteOwnerRefStrategicMergeBytes(pod.UID, []types.UID{m.Controller.GetUID()}, m.finalizers...)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -361,8 +361,8 @@ func (m *ReplicaSetControllerRefManager) AdoptReplicaSet(ctx context.Context, rs
|
||||
// ReleaseReplicaSet sends a patch to free the ReplicaSet from the control of the Deployment controller.
|
||||
// It returns the error if the patching fails. 404 and 422 errors are ignored.
|
||||
func (m *ReplicaSetControllerRefManager) ReleaseReplicaSet(ctx context.Context, replicaSet *apps.ReplicaSet) error {
|
||||
klog.V(2).Infof("patching ReplicaSet %s_%s to remove its controllerRef to %s/%s:%s",
|
||||
replicaSet.Namespace, replicaSet.Name, m.controllerKind.GroupVersion(), m.controllerKind.Kind, m.Controller.GetName())
|
||||
logger := klog.FromContext(ctx)
|
||||
logger.V(2).Info("Patching ReplicaSet to remove its controllerRef", "replicaSet", klog.KObj(replicaSet), "gvk", m.controllerKind, "controller", m.Controller.GetName())
|
||||
patchBytes, err := GenerateDeleteOwnerRefStrategicMergeBytes(replicaSet.UID, []types.UID{m.Controller.GetUID()})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -499,8 +499,8 @@ func (m *ControllerRevisionControllerRefManager) AdoptControllerRevision(ctx con
|
||||
// ReleaseControllerRevision sends a patch to free the ControllerRevision from the control of its controller.
|
||||
// It returns the error if the patching fails. 404 and 422 errors are ignored.
|
||||
func (m *ControllerRevisionControllerRefManager) ReleaseControllerRevision(ctx context.Context, history *apps.ControllerRevision) error {
|
||||
klog.V(2).Infof("patching ControllerRevision %s_%s to remove its controllerRef to %s/%s:%s",
|
||||
history.Namespace, history.Name, m.controllerKind.GroupVersion(), m.controllerKind.Kind, m.Controller.GetName())
|
||||
logger := klog.FromContext(ctx)
|
||||
logger.V(2).Info("Patching ControllerRevision to remove its controllerRef", "controllerRevision", klog.KObj(history), "gvk", m.controllerKind, "controller", m.Controller.GetName())
|
||||
patchBytes, err := GenerateDeleteOwnerRefStrategicMergeBytes(history.UID, []types.UID{m.Controller.GetUID()})
|
||||
if err != nil {
|
||||
return err
|
||||
|
137
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
137
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
@ -146,15 +146,15 @@ var ExpKeyFunc = func(obj interface{}) (string, error) {
|
||||
// types of controllers, because the keys might conflict across types.
|
||||
type ControllerExpectationsInterface interface {
|
||||
GetExpectations(controllerKey string) (*ControlleeExpectations, bool, error)
|
||||
SatisfiedExpectations(controllerKey string) bool
|
||||
DeleteExpectations(controllerKey string)
|
||||
SetExpectations(controllerKey string, add, del int) error
|
||||
ExpectCreations(controllerKey string, adds int) error
|
||||
ExpectDeletions(controllerKey string, dels int) error
|
||||
CreationObserved(controllerKey string)
|
||||
DeletionObserved(controllerKey string)
|
||||
RaiseExpectations(controllerKey string, add, del int)
|
||||
LowerExpectations(controllerKey string, add, del int)
|
||||
SatisfiedExpectations(logger klog.Logger, controllerKey string) bool
|
||||
DeleteExpectations(logger klog.Logger, controllerKey string)
|
||||
SetExpectations(logger klog.Logger, controllerKey string, add, del int) error
|
||||
ExpectCreations(logger klog.Logger, controllerKey string, adds int) error
|
||||
ExpectDeletions(logger klog.Logger, controllerKey string, dels int) error
|
||||
CreationObserved(logger klog.Logger, controllerKey string)
|
||||
DeletionObserved(logger klog.Logger, controllerKey string)
|
||||
RaiseExpectations(logger klog.Logger, controllerKey string, add, del int)
|
||||
LowerExpectations(logger klog.Logger, controllerKey string, add, del int)
|
||||
}
|
||||
|
||||
// ControllerExpectations is a cache mapping controllers to what they expect to see before being woken up for a sync.
|
||||
@ -172,10 +172,11 @@ func (r *ControllerExpectations) GetExpectations(controllerKey string) (*Control
|
||||
}
|
||||
|
||||
// DeleteExpectations deletes the expectations of the given controller from the TTLStore.
|
||||
func (r *ControllerExpectations) DeleteExpectations(controllerKey string) {
|
||||
func (r *ControllerExpectations) DeleteExpectations(logger klog.Logger, controllerKey string) {
|
||||
if exp, exists, err := r.GetByKey(controllerKey); err == nil && exists {
|
||||
if err := r.Delete(exp); err != nil {
|
||||
klog.V(2).Infof("Error deleting expectations for controller %v: %v", controllerKey, err)
|
||||
|
||||
logger.V(2).Info("Error deleting expectations", "controller", controllerKey, "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,27 +184,27 @@ func (r *ControllerExpectations) DeleteExpectations(controllerKey string) {
|
||||
// SatisfiedExpectations returns true if the required adds/dels for the given controller have been observed.
|
||||
// Add/del counts are established by the controller at sync time, and updated as controllees are observed by the controller
|
||||
// manager.
|
||||
func (r *ControllerExpectations) SatisfiedExpectations(controllerKey string) bool {
|
||||
func (r *ControllerExpectations) SatisfiedExpectations(logger klog.Logger, controllerKey string) bool {
|
||||
if exp, exists, err := r.GetExpectations(controllerKey); exists {
|
||||
if exp.Fulfilled() {
|
||||
klog.V(4).Infof("Controller expectations fulfilled %#v", exp)
|
||||
logger.V(4).Info("Controller expectations fulfilled", "expectations", exp)
|
||||
return true
|
||||
} else if exp.isExpired() {
|
||||
klog.V(4).Infof("Controller expectations expired %#v", exp)
|
||||
logger.V(4).Info("Controller expectations expired", "expectations", exp)
|
||||
return true
|
||||
} else {
|
||||
klog.V(4).Infof("Controller still waiting on expectations %#v", exp)
|
||||
logger.V(4).Info("Controller still waiting on expectations", "expectations", exp)
|
||||
return false
|
||||
}
|
||||
} else if err != nil {
|
||||
klog.V(2).Infof("Error encountered while checking expectations %#v, forcing sync", err)
|
||||
logger.V(2).Info("Error encountered while checking expectations, forcing sync", "err", err)
|
||||
} else {
|
||||
// When a new controller is created, it doesn't have expectations.
|
||||
// When it doesn't see expected watch events for > TTL, the expectations expire.
|
||||
// - In this case it wakes up, creates/deletes controllees, and sets expectations again.
|
||||
// When it has satisfied expectations and no controllees need to be created/destroyed > TTL, the expectations expire.
|
||||
// - In this case it continues without setting expectations till it needs to create/delete controllees.
|
||||
klog.V(4).Infof("Controller %v either never recorded expectations, or the ttl expired.", controllerKey)
|
||||
logger.V(4).Info("Controller either never recorded expectations, or the ttl expired", "controller", controllerKey)
|
||||
}
|
||||
// Trigger a sync if we either encountered and error (which shouldn't happen since we're
|
||||
// getting from local store) or this controller hasn't established expectations.
|
||||
@ -218,46 +219,46 @@ func (exp *ControlleeExpectations) isExpired() bool {
|
||||
}
|
||||
|
||||
// SetExpectations registers new expectations for the given controller. Forgets existing expectations.
|
||||
func (r *ControllerExpectations) SetExpectations(controllerKey string, add, del int) error {
|
||||
func (r *ControllerExpectations) SetExpectations(logger klog.Logger, controllerKey string, add, del int) error {
|
||||
exp := &ControlleeExpectations{add: int64(add), del: int64(del), key: controllerKey, timestamp: clock.RealClock{}.Now()}
|
||||
klog.V(4).Infof("Setting expectations %#v", exp)
|
||||
logger.V(4).Info("Setting expectations", "expectations", exp)
|
||||
return r.Add(exp)
|
||||
}
|
||||
|
||||
func (r *ControllerExpectations) ExpectCreations(controllerKey string, adds int) error {
|
||||
return r.SetExpectations(controllerKey, adds, 0)
|
||||
func (r *ControllerExpectations) ExpectCreations(logger klog.Logger, controllerKey string, adds int) error {
|
||||
return r.SetExpectations(logger, controllerKey, adds, 0)
|
||||
}
|
||||
|
||||
func (r *ControllerExpectations) ExpectDeletions(controllerKey string, dels int) error {
|
||||
return r.SetExpectations(controllerKey, 0, dels)
|
||||
func (r *ControllerExpectations) ExpectDeletions(logger klog.Logger, controllerKey string, dels int) error {
|
||||
return r.SetExpectations(logger, controllerKey, 0, dels)
|
||||
}
|
||||
|
||||
// Decrements the expectation counts of the given controller.
|
||||
func (r *ControllerExpectations) LowerExpectations(controllerKey string, add, del int) {
|
||||
func (r *ControllerExpectations) LowerExpectations(logger klog.Logger, controllerKey string, add, del int) {
|
||||
if exp, exists, err := r.GetExpectations(controllerKey); err == nil && exists {
|
||||
exp.Add(int64(-add), int64(-del))
|
||||
// The expectations might've been modified since the update on the previous line.
|
||||
klog.V(4).Infof("Lowered expectations %#v", exp)
|
||||
logger.V(4).Info("Lowered expectations", "expectations", exp)
|
||||
}
|
||||
}
|
||||
|
||||
// Increments the expectation counts of the given controller.
|
||||
func (r *ControllerExpectations) RaiseExpectations(controllerKey string, add, del int) {
|
||||
func (r *ControllerExpectations) RaiseExpectations(logger klog.Logger, controllerKey string, add, del int) {
|
||||
if exp, exists, err := r.GetExpectations(controllerKey); err == nil && exists {
|
||||
exp.Add(int64(add), int64(del))
|
||||
// The expectations might've been modified since the update on the previous line.
|
||||
klog.V(4).Infof("Raised expectations %#v", exp)
|
||||
logger.V(4).Info("Raised expectations", "expectations", exp)
|
||||
}
|
||||
}
|
||||
|
||||
// CreationObserved atomically decrements the `add` expectation count of the given controller.
|
||||
func (r *ControllerExpectations) CreationObserved(controllerKey string) {
|
||||
r.LowerExpectations(controllerKey, 1, 0)
|
||||
func (r *ControllerExpectations) CreationObserved(logger klog.Logger, controllerKey string) {
|
||||
r.LowerExpectations(logger, controllerKey, 1, 0)
|
||||
}
|
||||
|
||||
// DeletionObserved atomically decrements the `del` expectation count of the given controller.
|
||||
func (r *ControllerExpectations) DeletionObserved(controllerKey string) {
|
||||
r.LowerExpectations(controllerKey, 0, 1)
|
||||
func (r *ControllerExpectations) DeletionObserved(logger klog.Logger, controllerKey string) {
|
||||
r.LowerExpectations(logger, controllerKey, 0, 1)
|
||||
}
|
||||
|
||||
// ControlleeExpectations track controllee creates/deletes.
|
||||
@ -287,6 +288,20 @@ func (e *ControlleeExpectations) GetExpectations() (int64, int64) {
|
||||
return atomic.LoadInt64(&e.add), atomic.LoadInt64(&e.del)
|
||||
}
|
||||
|
||||
// MarshalLog makes a thread-safe copy of the values of the expectations that
|
||||
// can be used for logging.
|
||||
func (e *ControlleeExpectations) MarshalLog() interface{} {
|
||||
return struct {
|
||||
add int64
|
||||
del int64
|
||||
key string
|
||||
}{
|
||||
add: atomic.LoadInt64(&e.add),
|
||||
del: atomic.LoadInt64(&e.del),
|
||||
key: e.key,
|
||||
}
|
||||
}
|
||||
|
||||
// NewControllerExpectations returns a store for ControllerExpectations.
|
||||
func NewControllerExpectations() *ControllerExpectations {
|
||||
return &ControllerExpectations{cache.NewStore(ExpKeyFunc)}
|
||||
@ -335,47 +350,47 @@ func (u *UIDTrackingControllerExpectations) GetUIDs(controllerKey string) sets.S
|
||||
}
|
||||
|
||||
// ExpectDeletions records expectations for the given deleteKeys, against the given controller.
|
||||
func (u *UIDTrackingControllerExpectations) ExpectDeletions(rcKey string, deletedKeys []string) error {
|
||||
func (u *UIDTrackingControllerExpectations) ExpectDeletions(logger klog.Logger, rcKey string, deletedKeys []string) error {
|
||||
expectedUIDs := sets.NewString()
|
||||
for _, k := range deletedKeys {
|
||||
expectedUIDs.Insert(k)
|
||||
}
|
||||
klog.V(4).Infof("Controller %v waiting on deletions for: %+v", rcKey, deletedKeys)
|
||||
logger.V(4).Info("Controller waiting on deletions", "controller", rcKey, "keys", deletedKeys)
|
||||
u.uidStoreLock.Lock()
|
||||
defer u.uidStoreLock.Unlock()
|
||||
|
||||
if existing := u.GetUIDs(rcKey); existing != nil && existing.Len() != 0 {
|
||||
klog.Errorf("Clobbering existing delete keys: %+v", existing)
|
||||
logger.Error(nil, "Clobbering existing delete keys", "keys", existing)
|
||||
}
|
||||
if err := u.uidStore.Add(&UIDSet{expectedUIDs, rcKey}); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.ControllerExpectationsInterface.ExpectDeletions(rcKey, expectedUIDs.Len())
|
||||
return u.ControllerExpectationsInterface.ExpectDeletions(logger, rcKey, expectedUIDs.Len())
|
||||
}
|
||||
|
||||
// DeletionObserved records the given deleteKey as a deletion, for the given rc.
|
||||
func (u *UIDTrackingControllerExpectations) DeletionObserved(rcKey, deleteKey string) {
|
||||
func (u *UIDTrackingControllerExpectations) DeletionObserved(logger klog.Logger, rcKey, deleteKey string) {
|
||||
u.uidStoreLock.Lock()
|
||||
defer u.uidStoreLock.Unlock()
|
||||
|
||||
uids := u.GetUIDs(rcKey)
|
||||
if uids != nil && uids.Has(deleteKey) {
|
||||
klog.V(4).Infof("Controller %v received delete for pod %v", rcKey, deleteKey)
|
||||
u.ControllerExpectationsInterface.DeletionObserved(rcKey)
|
||||
logger.V(4).Info("Controller received delete for pod", "controller", rcKey, "key", deleteKey)
|
||||
u.ControllerExpectationsInterface.DeletionObserved(logger, rcKey)
|
||||
uids.Delete(deleteKey)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteExpectations deletes the UID set and invokes DeleteExpectations on the
|
||||
// underlying ControllerExpectationsInterface.
|
||||
func (u *UIDTrackingControllerExpectations) DeleteExpectations(rcKey string) {
|
||||
func (u *UIDTrackingControllerExpectations) DeleteExpectations(logger klog.Logger, rcKey string) {
|
||||
u.uidStoreLock.Lock()
|
||||
defer u.uidStoreLock.Unlock()
|
||||
|
||||
u.ControllerExpectationsInterface.DeleteExpectations(rcKey)
|
||||
u.ControllerExpectationsInterface.DeleteExpectations(logger, rcKey)
|
||||
if uidExp, exists, err := u.uidStore.GetByKey(rcKey); err == nil && exists {
|
||||
if err := u.uidStore.Delete(uidExp); err != nil {
|
||||
klog.V(2).Infof("Error deleting uid expectations for controller %v: %v", rcKey, err)
|
||||
logger.V(2).Info("Error deleting uid expectations", "controller", rcKey, "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -573,12 +588,13 @@ func (r RealPodControl) createPods(ctx context.Context, namespace string, pod *v
|
||||
}
|
||||
return err
|
||||
}
|
||||
logger := klog.FromContext(ctx)
|
||||
accessor, err := meta.Accessor(object)
|
||||
if err != nil {
|
||||
klog.Errorf("parentObject does not have ObjectMeta, %v", err)
|
||||
logger.Error(err, "parentObject does not have ObjectMeta")
|
||||
return nil
|
||||
}
|
||||
klog.V(4).Infof("Controller %v created pod %v", accessor.GetName(), newPod.Name)
|
||||
logger.V(4).Info("Controller created pod", "controller", accessor.GetName(), "pod", klog.KObj(newPod))
|
||||
r.Recorder.Eventf(object, v1.EventTypeNormal, SuccessfulCreatePodReason, "Created pod: %v", newPod.Name)
|
||||
|
||||
return nil
|
||||
@ -589,10 +605,11 @@ func (r RealPodControl) DeletePod(ctx context.Context, namespace string, podID s
|
||||
if err != nil {
|
||||
return fmt.Errorf("object does not have ObjectMeta, %v", err)
|
||||
}
|
||||
klog.V(2).InfoS("Deleting pod", "controller", accessor.GetName(), "pod", klog.KRef(namespace, podID))
|
||||
logger := klog.FromContext(ctx)
|
||||
logger.V(2).Info("Deleting pod", "controller", accessor.GetName(), "pod", klog.KRef(namespace, podID))
|
||||
if err := r.KubeClient.CoreV1().Pods(namespace).Delete(ctx, podID, metav1.DeleteOptions{}); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
klog.V(4).Infof("pod %v/%v has already been deleted.", namespace, podID)
|
||||
logger.V(4).Info("Pod has already been deleted.", "pod", klog.KRef(namespace, podID))
|
||||
return err
|
||||
}
|
||||
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedDeletePodReason, "Error deleting: %v", err)
|
||||
@ -929,25 +946,49 @@ func maxContainerRestarts(pod *v1.Pod) int {
|
||||
}
|
||||
|
||||
// FilterActivePods returns pods that have not terminated.
|
||||
func FilterActivePods(pods []*v1.Pod) []*v1.Pod {
|
||||
func FilterActivePods(logger klog.Logger, pods []*v1.Pod) []*v1.Pod {
|
||||
var result []*v1.Pod
|
||||
for _, p := range pods {
|
||||
if IsPodActive(p) {
|
||||
result = append(result, p)
|
||||
} else {
|
||||
klog.V(4).Infof("Ignoring inactive pod %v/%v in state %v, deletion time %v",
|
||||
p.Namespace, p.Name, p.Status.Phase, p.DeletionTimestamp)
|
||||
logger.V(4).Info("Ignoring inactive pod", "pod", klog.KObj(p), "phase", p.Status.Phase, "deletionTime", p.DeletionTimestamp)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func FilterTerminatingPods(pods []*v1.Pod) []*v1.Pod {
|
||||
var result []*v1.Pod
|
||||
for _, p := range pods {
|
||||
if IsPodTerminating(p) {
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func CountTerminatingPods(pods []*v1.Pod) int32 {
|
||||
numberOfTerminatingPods := 0
|
||||
for _, p := range pods {
|
||||
if IsPodTerminating(p) {
|
||||
numberOfTerminatingPods += 1
|
||||
}
|
||||
}
|
||||
return int32(numberOfTerminatingPods)
|
||||
}
|
||||
|
||||
func IsPodActive(p *v1.Pod) bool {
|
||||
return v1.PodSucceeded != p.Status.Phase &&
|
||||
v1.PodFailed != p.Status.Phase &&
|
||||
p.DeletionTimestamp == nil
|
||||
}
|
||||
|
||||
func IsPodTerminating(p *v1.Pod) bool {
|
||||
return !podutil.IsPodTerminal(p) &&
|
||||
p.DeletionTimestamp != nil
|
||||
}
|
||||
|
||||
// FilterActiveReplicaSets returns replica sets that have (or at least ought to have) pods.
|
||||
func FilterActiveReplicaSets(replicaSets []*apps.ReplicaSet) []*apps.ReplicaSet {
|
||||
activeFilter := func(rs *apps.ReplicaSet) bool {
|
||||
|
12
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
@ -184,12 +184,12 @@ func SetDeploymentRevision(deployment *apps.Deployment, revision string) bool {
|
||||
}
|
||||
|
||||
// MaxRevision finds the highest revision in the replica sets
|
||||
func MaxRevision(allRSs []*apps.ReplicaSet) int64 {
|
||||
func MaxRevision(logger klog.Logger, allRSs []*apps.ReplicaSet) int64 {
|
||||
max := int64(0)
|
||||
for _, rs := range allRSs {
|
||||
if v, err := Revision(rs); err != nil {
|
||||
// Skip the replica sets when it failed to parse their revision information
|
||||
klog.V(4).Info("Couldn't parse revision for replica set, deployment controller will skip it when reconciling revisions", "replicaSet", klog.KObj(rs), "err", err)
|
||||
logger.V(4).Info("Couldn't parse revision for replica set, deployment controller will skip it when reconciling revisions", "replicaSet", klog.KObj(rs), "err", err)
|
||||
} else if v > max {
|
||||
max = v
|
||||
}
|
||||
@ -198,12 +198,12 @@ func MaxRevision(allRSs []*apps.ReplicaSet) int64 {
|
||||
}
|
||||
|
||||
// LastRevision finds the second max revision number in all replica sets (the last revision)
|
||||
func LastRevision(allRSs []*apps.ReplicaSet) int64 {
|
||||
func LastRevision(logger klog.Logger, allRSs []*apps.ReplicaSet) int64 {
|
||||
max, secMax := int64(0), int64(0)
|
||||
for _, rs := range allRSs {
|
||||
if v, err := Revision(rs); err != nil {
|
||||
// Skip the replica sets when it failed to parse their revision information
|
||||
klog.V(4).Info("Couldn't parse revision for replica set, deployment controller will skip it when reconciling revisions", "replicaSet", klog.KObj(rs), "err", err)
|
||||
logger.V(4).Info("Couldn't parse revision for replica set, deployment controller will skip it when reconciling revisions", "replicaSet", klog.KObj(rs), "err", err)
|
||||
} else if v >= max {
|
||||
secMax = max
|
||||
max = v
|
||||
@ -849,11 +849,11 @@ func WaitForObservedDeployment(getDeploymentFunc func() (*apps.Deployment, error
|
||||
// 2 desired, max unavailable 0%, surge 1% - should scale new(+1), then old(-1), then new(+1), then old(-1)
|
||||
// 1 desired, max unavailable 0%, surge 1% - should scale new(+1), then old(-1)
|
||||
func ResolveFenceposts(maxSurge, maxUnavailable *intstrutil.IntOrString, desired int32) (int32, int32, error) {
|
||||
surge, err := intstrutil.GetScaledValueFromIntOrPercent(intstrutil.ValueOrDefault(maxSurge, intstrutil.FromInt(0)), int(desired), true)
|
||||
surge, err := intstrutil.GetScaledValueFromIntOrPercent(intstrutil.ValueOrDefault(maxSurge, intstrutil.FromInt32(0)), int(desired), true)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
unavailable, err := intstrutil.GetScaledValueFromIntOrPercent(intstrutil.ValueOrDefault(maxUnavailable, intstrutil.FromInt(0)), int(desired), false)
|
||||
unavailable, err := intstrutil.GetScaledValueFromIntOrPercent(intstrutil.ValueOrDefault(maxUnavailable, intstrutil.FromInt32(0)), int(desired), false)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
92
vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go
generated
vendored
92
vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go
generated
vendored
@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"hash/fnv"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/groupcache/lru"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||
)
|
||||
|
||||
type objectWithMeta interface {
|
||||
metav1.Object
|
||||
}
|
||||
|
||||
// keyFunc returns the key of an object, which is used to look up in the cache for it's matching object.
|
||||
// Since we match objects by namespace and Labels/Selector, so if two objects have the same namespace and labels,
|
||||
// they will have the same key.
|
||||
func keyFunc(obj objectWithMeta) uint64 {
|
||||
hash := fnv.New32a()
|
||||
hashutil.DeepHashObject(hash, &equivalenceLabelObj{
|
||||
namespace: obj.GetNamespace(),
|
||||
labels: obj.GetLabels(),
|
||||
})
|
||||
return uint64(hash.Sum32())
|
||||
}
|
||||
|
||||
type equivalenceLabelObj struct {
|
||||
namespace string
|
||||
labels map[string]string
|
||||
}
|
||||
|
||||
// MatchingCache save label and selector matching relationship
|
||||
type MatchingCache struct {
|
||||
mutex sync.RWMutex
|
||||
cache *lru.Cache
|
||||
}
|
||||
|
||||
// NewMatchingCache return a NewMatchingCache, which save label and selector matching relationship.
|
||||
func NewMatchingCache(maxCacheEntries int) *MatchingCache {
|
||||
return &MatchingCache{
|
||||
cache: lru.New(maxCacheEntries),
|
||||
}
|
||||
}
|
||||
|
||||
// Add will add matching information to the cache.
|
||||
func (c *MatchingCache) Add(labelObj objectWithMeta, selectorObj objectWithMeta) {
|
||||
key := keyFunc(labelObj)
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
c.cache.Add(key, selectorObj)
|
||||
}
|
||||
|
||||
// GetMatchingObject lookup the matching object for a given object.
|
||||
// Note: the cache information may be invalid since the controller may be deleted or updated,
|
||||
// we need check in the external request to ensure the cache data is not dirty.
|
||||
func (c *MatchingCache) GetMatchingObject(labelObj objectWithMeta) (controller interface{}, exists bool) {
|
||||
key := keyFunc(labelObj)
|
||||
// NOTE: we use Lock() instead of RLock() here because lru's Get() method also modifies state(
|
||||
// it need update the least recently usage information). So we can not call it concurrently.
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
return c.cache.Get(key)
|
||||
}
|
||||
|
||||
// Update update the cached matching information.
|
||||
func (c *MatchingCache) Update(labelObj objectWithMeta, selectorObj objectWithMeta) {
|
||||
c.Add(labelObj, selectorObj)
|
||||
}
|
||||
|
||||
// InvalidateAll invalidate the whole cache.
|
||||
func (c *MatchingCache) InvalidateAll() {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
c.cache = lru.New(c.cache.MaxEntries)
|
||||
}
|
358
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
358
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package features
|
||||
|
||||
import (
|
||||
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
@ -53,6 +54,7 @@ const (
|
||||
// owner: @nabokihms
|
||||
// alpha: v1.26
|
||||
// beta: v1.27
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enables API to get self subject attributes after authentication.
|
||||
APISelfSubjectReview featuregate.Feature = "APISelfSubjectReview"
|
||||
@ -129,13 +131,11 @@ const (
|
||||
// Enables the Azure File in-tree driver to Azure File Driver migration feature.
|
||||
CSIMigrationAzureFile featuregate.Feature = "CSIMigrationAzureFile"
|
||||
|
||||
// owner: @davidz627
|
||||
// alpha: v1.14
|
||||
// beta: v1.17
|
||||
// GA: 1.25
|
||||
// owner: @mfordjody
|
||||
// alpha: v1.26
|
||||
//
|
||||
// Enables the GCE PD in-tree driver to GCE CSI Driver migration feature.
|
||||
CSIMigrationGCE featuregate.Feature = "CSIMigrationGCE"
|
||||
// Skip validation Enable in next version
|
||||
SkipReadOnlyValidationGCE featuregate.Feature = "SkipReadOnlyValidationGCE"
|
||||
|
||||
// owner: @trierra
|
||||
// alpha: v1.23
|
||||
@ -145,6 +145,7 @@ const (
|
||||
|
||||
// owner: @humblec
|
||||
// alpha: v1.23
|
||||
// deprecated: v1.28
|
||||
//
|
||||
// Enables the RBD in-tree driver to RBD CSI Driver migration feature.
|
||||
CSIMigrationRBD featuregate.Feature = "CSIMigrationRBD"
|
||||
@ -163,14 +164,6 @@ const (
|
||||
// Enables SecretRef field in CSI NodeExpandVolume request.
|
||||
CSINodeExpandSecret featuregate.Feature = "CSINodeExpandSecret"
|
||||
|
||||
// owner: @pohly
|
||||
// alpha: v1.19
|
||||
// beta: v1.21
|
||||
// GA: v1.24
|
||||
//
|
||||
// Enables tracking of available storage capacity that CSI drivers provide.
|
||||
CSIStorageCapacity featuregate.Feature = "CSIStorageCapacity"
|
||||
|
||||
// owner: @fengzixu
|
||||
// alpha: v1.21
|
||||
//
|
||||
@ -196,6 +189,11 @@ const (
|
||||
// Normalize HttpGet URL and Header passing for lifecycle handlers with probers.
|
||||
ConsistentHTTPGetHandlers featuregate.Feature = "ConsistentHTTPGetHandlers"
|
||||
|
||||
// owner: @helayoty
|
||||
// beta: v1.28
|
||||
// Set the scheduled time as an annotation in the job.
|
||||
CronJobsScheduledAnnotation featuregate.Feature = "CronJobsScheduledAnnotation"
|
||||
|
||||
// owner: @deejross, @soltysh
|
||||
// kep: https://kep.k8s.io/3140
|
||||
// alpha: v1.24
|
||||
@ -205,30 +203,21 @@ const (
|
||||
// Enables support for time zones in CronJobs.
|
||||
CronJobTimeZone featuregate.Feature = "CronJobTimeZone"
|
||||
|
||||
// owner: @gnufied, @verult, @bertinatto
|
||||
// alpha: v1.22
|
||||
// beta: v1.23
|
||||
// GA: v1.26
|
||||
// If supported by the CSI driver, delegates the role of applying FSGroup to
|
||||
// the driver by passing FSGroup through the NodeStageVolume and
|
||||
// NodePublishVolume calls.
|
||||
DelegateFSGroupToCSIDriver featuregate.Feature = "DelegateFSGroupToCSIDriver"
|
||||
|
||||
// owner: @jiayingz, @swatisehgal (for GA graduation)
|
||||
// alpha: v1.8
|
||||
// beta: v1.10
|
||||
// GA: v1.26
|
||||
// owner: @thockin
|
||||
// deprecated: v1.28
|
||||
//
|
||||
// Enables support for Device Plugins
|
||||
DevicePlugins featuregate.Feature = "DevicePlugins"
|
||||
// Changes when the default value of PodSpec.containers[].ports[].hostPort
|
||||
// is assigned. The default is to only set a default value in Pods.
|
||||
// Enabling this means a default will be assigned even to embeddedPodSpecs
|
||||
// (e.g. in a Deployment), which is the historical default.
|
||||
DefaultHostNetworkHostPortsInPodTemplates featuregate.Feature = "DefaultHostNetworkHostPortsInPodTemplates"
|
||||
|
||||
// owner: @RenaudWasTaken @dashpole
|
||||
// alpha: v1.19
|
||||
// beta: v1.20
|
||||
// ga: v1.25
|
||||
// owner: @elezar
|
||||
// kep: http://kep.k8s.io/4009
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Disables Accelerator Metrics Collected by Kubelet
|
||||
DisableAcceleratorUsageMetrics featuregate.Feature = "DisableAcceleratorUsageMetrics"
|
||||
// Add support for CDI Device IDs in the Device Plugin API.
|
||||
DevicePluginCDIDevices featuregate.Feature = "DevicePluginCDIDevices"
|
||||
|
||||
// owner: @andrewsykim
|
||||
// alpha: v1.22
|
||||
@ -258,15 +247,6 @@ const (
|
||||
// that is independent of a Pod.
|
||||
DynamicResourceAllocation featuregate.Feature = "DynamicResourceAllocation"
|
||||
|
||||
// owner: @andrewsykim
|
||||
// kep: https://kep.k8s.io/1672
|
||||
// alpha: v1.20
|
||||
// beta: v1.22
|
||||
// GA: v1.26
|
||||
//
|
||||
// Enable Terminating condition in Endpoint Slices.
|
||||
EndpointSliceTerminatingCondition featuregate.Feature = "EndpointSliceTerminatingCondition"
|
||||
|
||||
// owner: @harche
|
||||
// kep: http://kep.k8s.io/3386
|
||||
// alpha: v1.25
|
||||
@ -288,16 +268,16 @@ const (
|
||||
// kep: https://kep.k8s.io/2595
|
||||
// alpha: v1.22
|
||||
// beta: v1.26
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enables apiserver and kubelet to allow up to 32 DNSSearchPaths and up to 2048 DNSSearchListChars.
|
||||
ExpandedDNSConfig featuregate.Feature = "ExpandedDNSConfig"
|
||||
|
||||
// owner: @pweil-
|
||||
// alpha: v1.5
|
||||
// deprecated: v1.28
|
||||
//
|
||||
// Default userns=host for containers that are using other host namespaces, host mounts, the pod
|
||||
// contains a privileged container, or specific non-namespaced capabilities (MKNOD, SYS_MODULE,
|
||||
// SYS_TIME). This should only be enabled if user namespace remapping is enabled in the docker daemon.
|
||||
// This flag used to be needed for dockershim CRI and currently does nothing.
|
||||
ExperimentalHostUserNamespaceDefaultingGate featuregate.Feature = "ExperimentalHostUserNamespaceDefaulting"
|
||||
|
||||
// owner: @yuzhiquan, @bowei, @PxyUp, @SergeyKanzhelev
|
||||
@ -382,6 +362,7 @@ const (
|
||||
|
||||
// owner: @humblec
|
||||
// alpha: v1.23
|
||||
// deprecated: v1.28
|
||||
//
|
||||
// Disables the RBD in-tree driver.
|
||||
InTreePluginRBDUnregister featuregate.Feature = "InTreePluginRBDUnregister"
|
||||
@ -396,18 +377,17 @@ const (
|
||||
// kep: https://kep.k8s.io/3178
|
||||
// alpha: v1.25
|
||||
// beta: v1.27
|
||||
// stable: v1.28
|
||||
//
|
||||
// Causes kubelet to no longer create legacy IPTables rules
|
||||
IPTablesOwnershipCleanup featuregate.Feature = "IPTablesOwnershipCleanup"
|
||||
|
||||
// owner: @mimowo
|
||||
// kep: https://kep.k8s.io/3329
|
||||
// alpha: v1.25
|
||||
// beta: v1.26
|
||||
// kep: https://kep.k8s.io/3850
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Allow users to specify handling of pod failures based on container exit codes
|
||||
// and pod conditions.
|
||||
JobPodFailurePolicy featuregate.Feature = "JobPodFailurePolicy"
|
||||
// Allows users to specify counting of failed pods per index.
|
||||
JobBackoffLimitPerIndex featuregate.Feature = "JobBackoffLimitPerIndex"
|
||||
|
||||
// owner: @ahg
|
||||
// beta: v1.23
|
||||
@ -418,6 +398,22 @@ const (
|
||||
// that have never been unsuspended before.
|
||||
JobMutableNodeSchedulingDirectives featuregate.Feature = "JobMutableNodeSchedulingDirectives"
|
||||
|
||||
// owner: @mimowo
|
||||
// kep: https://kep.k8s.io/3329
|
||||
// alpha: v1.25
|
||||
// beta: v1.26
|
||||
//
|
||||
// Allow users to specify handling of pod failures based on container exit codes
|
||||
// and pod conditions.
|
||||
JobPodFailurePolicy featuregate.Feature = "JobPodFailurePolicy"
|
||||
|
||||
// owner: @kannon92
|
||||
// kep : https://kep.k8s.io/3939
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Allow users to specify recreating pods of a job only when
|
||||
// pods have fully terminated.
|
||||
JobPodReplacementPolicy featuregate.Feature = "JobPodReplacementPolicy"
|
||||
// owner: @alculquicondor
|
||||
// alpha: v1.23
|
||||
// beta: v1.24
|
||||
@ -436,13 +432,16 @@ const (
|
||||
// yet.
|
||||
JobTrackingWithFinalizers featuregate.Feature = "JobTrackingWithFinalizers"
|
||||
|
||||
// owner: @andrewsykim @adisky @ndixita
|
||||
// alpha: v1.20
|
||||
// beta: v1.24
|
||||
// GA: v1.26
|
||||
// owner: @marquiz
|
||||
// kep: http://kep.k8s.io/4033
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Enable kubelet exec plugins for image pull credentials.
|
||||
KubeletCredentialProviders featuregate.Feature = "KubeletCredentialProviders"
|
||||
// Enable detection of the kubelet cgroup driver configuration option from
|
||||
// the CRI. The CRI runtime also needs to support this feature in which
|
||||
// case the kubelet will ignore the cgroupDriver (--cgroup-driver)
|
||||
// configuration option. If runtime doesn't support it, the kubelet will
|
||||
// fallback to using it's cgroupDriver option.
|
||||
KubeletCgroupDriverFromCRI featuregate.Feature = "KubeletCgroupDriverFromCRI"
|
||||
|
||||
// owner: @AkihiroSuda
|
||||
// alpha: v1.22
|
||||
@ -452,9 +451,10 @@ const (
|
||||
// All the node components such as CRI need to be running in the same user namespace.
|
||||
KubeletInUserNamespace featuregate.Feature = "KubeletInUserNamespace"
|
||||
|
||||
// owner: @dashpole
|
||||
// owner: @dashpole, @ffromani (only for GA graduation)
|
||||
// alpha: v1.13
|
||||
// beta: v1.15
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enables the kubelet's pod resources grpc endpoint
|
||||
KubeletPodResources featuregate.Feature = "KubeletPodResources"
|
||||
@ -471,9 +471,10 @@ const (
|
||||
// Enable POD resources API with Get method
|
||||
KubeletPodResourcesGet featuregate.Feature = "KubeletPodResourcesGet"
|
||||
|
||||
// owner: @fromanirh
|
||||
// owner: @ffromani
|
||||
// alpha: v1.21
|
||||
// beta: v1.23
|
||||
// GA: v1.28
|
||||
// Enable POD resources API to return allocatable resources
|
||||
KubeletPodResourcesGetAllocatable featuregate.Feature = "KubeletPodResourcesGetAllocatable"
|
||||
|
||||
@ -485,6 +486,14 @@ const (
|
||||
// Add support for distributed tracing in the kubelet
|
||||
KubeletTracing featuregate.Feature = "KubeletTracing"
|
||||
|
||||
// owner: @alexanderConstantinescu
|
||||
// kep: http://kep.k8s.io/3836
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Implement connection draining for terminating nodes for
|
||||
// `externalTrafficPolicy: Cluster` services.
|
||||
KubeProxyDrainingTerminatingNodes featuregate.Feature = "KubeProxyDrainingTerminatingNodes"
|
||||
|
||||
// owner: @zshihang
|
||||
// kep: https://kep.k8s.io/2800
|
||||
// beta: v1.24
|
||||
@ -501,6 +510,13 @@ const (
|
||||
// Enables tracking of secret-based service account tokens usage.
|
||||
LegacyServiceAccountTokenTracking featuregate.Feature = "LegacyServiceAccountTokenTracking"
|
||||
|
||||
// owner: @yt2985
|
||||
// kep: http://kep.k8s.io/2800
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Enables cleaning up of secret-based service account tokens.
|
||||
LegacyServiceAccountTokenCleanUp featuregate.Feature = "LegacyServiceAccountTokenCleanUp"
|
||||
|
||||
// owner: @RobertKrawitz
|
||||
// alpha: v1.15
|
||||
//
|
||||
@ -558,15 +574,6 @@ const (
|
||||
// Enables new performance-improving code in kube-proxy iptables mode
|
||||
MinimizeIPTablesRestore featuregate.Feature = "MinimizeIPTablesRestore"
|
||||
|
||||
// owner: @janosi @bridgetkromhout
|
||||
// kep: https://kep.k8s.io/1435
|
||||
// alpha: v1.20
|
||||
// beta: v1.24
|
||||
// ga: v1.26
|
||||
//
|
||||
// Enables the usage of different protocols in the same Service with type=LoadBalancer
|
||||
MixedProtocolLBService featuregate.Feature = "MixedProtocolLBService"
|
||||
|
||||
// owner: @sarveshr7
|
||||
// kep: https://kep.k8s.io/2593
|
||||
// alpha: v1.25
|
||||
@ -581,13 +588,6 @@ const (
|
||||
// Enables the dynamic configuration of Service IP ranges
|
||||
MultiCIDRServiceAllocator featuregate.Feature = "MultiCIDRServiceAllocator"
|
||||
|
||||
// owner: @rikatz
|
||||
// kep: https://kep.k8s.io/2943
|
||||
// alpha: v1.24
|
||||
//
|
||||
// Enables NetworkPolicy status subresource
|
||||
NetworkPolicyStatus featuregate.Feature = "NetworkPolicyStatus"
|
||||
|
||||
// owner: @jsafrane
|
||||
// kep: https://kep.k8s.io/3756
|
||||
// alpha: v1.25 (as part of SELinuxMountReadWriteOncePod)
|
||||
@ -606,12 +606,14 @@ const (
|
||||
// kep: https://kep.k8s.io/2268
|
||||
// alpha: v1.24
|
||||
// beta: v1.26
|
||||
// GA: v1.28
|
||||
//
|
||||
// Allow pods to failover to a different node in case of non graceful node shutdown
|
||||
NodeOutOfServiceVolumeDetach featuregate.Feature = "NodeOutOfServiceVolumeDetach"
|
||||
|
||||
// owner: @ehashman
|
||||
// owner: @iholder101
|
||||
// alpha: v1.22
|
||||
// beta1: v1.28. For more info, please look at the KEP: https://kep.k8s.io/2400.
|
||||
//
|
||||
// Permits kubelet to run with swap enabled
|
||||
NodeSwap featuregate.Feature = "NodeSwap"
|
||||
@ -624,6 +626,13 @@ const (
|
||||
// Enables PDBUnhealthyPodEvictionPolicy for PodDisruptionBudgets
|
||||
PDBUnhealthyPodEvictionPolicy featuregate.Feature = "PDBUnhealthyPodEvictionPolicy"
|
||||
|
||||
// owner: @RomanBednar
|
||||
// kep: https://kep.k8s.io/3762
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Adds a new field to persistent volumes which holds a timestamp of when the volume last transitioned its phase.
|
||||
PersistentVolumeLastPhaseTransitionTime featuregate.Feature = "PersistentVolumeLastPhaseTransitionTime"
|
||||
|
||||
// owner: @haircommander
|
||||
// kep: https://kep.k8s.io/2364
|
||||
// alpha: v1.23
|
||||
@ -648,12 +657,26 @@ const (
|
||||
// the pod is being deleted due to a disruption.
|
||||
PodDisruptionConditions featuregate.Feature = "PodDisruptionConditions"
|
||||
|
||||
// owner: @danielvegamyhre
|
||||
// kep: https://kep.k8s.io/4017
|
||||
// beta: v1.28
|
||||
//
|
||||
// Set pod completion index as a pod label for Indexed Jobs.
|
||||
PodIndexLabel featuregate.Feature = "PodIndexLabel"
|
||||
|
||||
// owner: @ddebroy
|
||||
// alpha: v1.25
|
||||
//
|
||||
// Enables reporting of PodHasNetwork condition in pod status after pod
|
||||
// Enables reporting of PodReadyToStartContainersCondition condition in pod status after pod
|
||||
// sandbox creation and network configuration completes successfully
|
||||
PodHasNetworkCondition featuregate.Feature = "PodHasNetworkCondition"
|
||||
PodReadyToStartContainersCondition featuregate.Feature = "PodReadyToStartContainersCondition"
|
||||
|
||||
// owner: @wzshiming
|
||||
// kep: http://kep.k8s.io/2681
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Adds pod.status.hostIPs and downward API
|
||||
PodHostIPs featuregate.Feature = "PodHostIPs"
|
||||
|
||||
// owner: @Huang-Wei
|
||||
// kep: https://kep.k8s.io/3521
|
||||
@ -663,17 +686,10 @@ const (
|
||||
// Enable users to specify when a Pod is ready for scheduling.
|
||||
PodSchedulingReadiness featuregate.Feature = "PodSchedulingReadiness"
|
||||
|
||||
// owner: @liggitt, @tallclair, sig-auth
|
||||
// alpha: v1.22
|
||||
// beta: v1.23
|
||||
// ga: v1.25
|
||||
//
|
||||
// Enables the PodSecurity admission plugin
|
||||
PodSecurity featuregate.Feature = "PodSecurity"
|
||||
|
||||
// owner: @ehashman
|
||||
// owner: @rphillips
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
// ga: v1.28
|
||||
//
|
||||
// Allows user to override pod-level terminationGracePeriod for probes
|
||||
ProbeTerminationGracePeriod featuregate.Feature = "ProbeTerminationGracePeriod"
|
||||
@ -688,6 +704,7 @@ const (
|
||||
// kep: https://kep.k8s.io/1669
|
||||
// alpha: v1.22
|
||||
// beta: v1.26
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enable kube-proxy to handle terminating ednpoints when externalTrafficPolicy=Local
|
||||
ProxyTerminatingEndpoints featuregate.Feature = "ProxyTerminatingEndpoints"
|
||||
@ -717,6 +734,8 @@ const (
|
||||
// owner: @RomanBednar
|
||||
// kep: https://kep.k8s.io/3333
|
||||
// alpha: v1.25
|
||||
// beta: 1.26
|
||||
// stable: v1.28
|
||||
//
|
||||
// Allow assigning StorageClass to unbound PVCs retroactively
|
||||
RetroactiveDefaultStorageClass featuregate.Feature = "RetroactiveDefaultStorageClass"
|
||||
@ -739,6 +758,14 @@ const (
|
||||
// equals to spec.parallelism before and after the update.
|
||||
ElasticIndexedJob featuregate.Feature = "ElasticIndexedJob"
|
||||
|
||||
// owner: @sanposhiho
|
||||
// kep: http://kep.k8s.io/3063
|
||||
// beta: v1.28
|
||||
//
|
||||
// Enables the scheduler's enhancement called QueueingHints,
|
||||
// which benefits to reduce the useless requeueing.
|
||||
SchedulerQueueingHints featuregate.Feature = "SchedulerQueueingHints"
|
||||
|
||||
// owner: @saschagrunert
|
||||
// kep: https://kep.k8s.io/2413
|
||||
// alpha: v1.22
|
||||
@ -756,31 +783,23 @@ const (
|
||||
// https://github.com/kubernetes/kubernetes/issues/111516
|
||||
SecurityContextDeny featuregate.Feature = "SecurityContextDeny"
|
||||
|
||||
// owner: @maplain @andrewsykim
|
||||
// kep: https://kep.k8s.io/2086
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
// GA: v1.26
|
||||
//
|
||||
// Enables node-local routing for Service internal traffic
|
||||
ServiceInternalTrafficPolicy featuregate.Feature = "ServiceInternalTrafficPolicy"
|
||||
|
||||
// owner: @aojea
|
||||
// kep: https://kep.k8s.io/3070
|
||||
// alpha: v1.24
|
||||
// beta: v1.25
|
||||
// ga: v1.26
|
||||
//
|
||||
// Subdivide the ClusterIP range for dynamic and static IP allocation.
|
||||
ServiceIPStaticSubrange featuregate.Feature = "ServiceIPStaticSubrange"
|
||||
|
||||
// owner: @xuzhenglun
|
||||
// kep: http://kep.k8s.io/3682
|
||||
// alpha: v1.27
|
||||
// beta: v1.28
|
||||
//
|
||||
// Subdivide the NodePort range for dynamic and static port allocation.
|
||||
ServiceNodePortStaticSubrange featuregate.Feature = "ServiceNodePortStaticSubrange"
|
||||
|
||||
// owner: @gjkim42 @SergeyKanzhelev @matthyx @tzneal
|
||||
// kep: http://kep.k8s.io/753
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Introduces sidecar containers, a new type of init container that starts
|
||||
// before other containers but remains running for the full duration of the
|
||||
// pod's lifecycle and will not block pod termination.
|
||||
SidecarContainers featuregate.Feature = "SidecarContainers"
|
||||
|
||||
// owner: @derekwaynecarr
|
||||
// alpha: v1.20
|
||||
// beta: v1.22
|
||||
@ -854,12 +873,18 @@ const (
|
||||
// Allow the usage of options to fine-tune the topology manager policies.
|
||||
TopologyManagerPolicyOptions featuregate.Feature = "TopologyManagerPolicyOptions"
|
||||
|
||||
// owner: @richabanker
|
||||
// alpha: v1.28
|
||||
//
|
||||
// Proxies client to an apiserver capable of serving the request in the event of version skew.
|
||||
UnknownVersionInteroperabilityProxy featuregate.Feature = "UnknownVersionInteroperabilityProxy"
|
||||
|
||||
// owner: @rata, @giuseppe
|
||||
// kep: https://kep.k8s.io/127
|
||||
// alpha: v1.25
|
||||
//
|
||||
// Enables user namespace support for stateless pods.
|
||||
UserNamespacesStatelessPodsSupport featuregate.Feature = "UserNamespacesStatelessPodsSupport"
|
||||
UserNamespacesSupport featuregate.Feature = "UserNamespacesSupport"
|
||||
|
||||
// owner: @cofyc
|
||||
// alpha: v1.21
|
||||
@ -885,14 +910,6 @@ const (
|
||||
// Enables support for joining Windows containers to a hosts' network namespace.
|
||||
WindowsHostNetwork featuregate.Feature = "WindowsHostNetwork"
|
||||
|
||||
// owner: @marosset
|
||||
// alpha: v1.22
|
||||
// beta: v1.23
|
||||
// GA: v1.26
|
||||
//
|
||||
// Enables support for 'HostProcess' containers on Windows nodes.
|
||||
WindowsHostProcessContainers featuregate.Feature = "WindowsHostProcessContainers"
|
||||
|
||||
// owner: @kerthcet
|
||||
// kep: https://kep.k8s.io/3094
|
||||
// alpha: v1.25
|
||||
@ -934,7 +951,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
AnyVolumeDataSource: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.24
|
||||
|
||||
APISelfSubjectReview: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.27
|
||||
APISelfSubjectReview: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.28; remove in 1.30
|
||||
|
||||
AppArmor: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
@ -954,41 +971,37 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
CSIMigrationAzureFile: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
CSIMigrationGCE: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27
|
||||
|
||||
CSIMigrationPortworx: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires Portworx CSI driver)
|
||||
|
||||
CSIMigrationRBD: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires RBD CSI driver)
|
||||
CSIMigrationRBD: {Default: false, PreRelease: featuregate.Deprecated}, // deprecated in 1.28, remove in 1.31
|
||||
|
||||
CSIMigrationvSphere: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
CSINodeExpandSecret: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
|
||||
|
||||
CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
SkipReadOnlyValidationGCE: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ContainerCheckpoint: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ConsistentHTTPGetHandlers: {Default: true, PreRelease: featuregate.GA},
|
||||
|
||||
CronJobsScheduledAnnotation: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
CronJobTimeZone: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
DelegateFSGroupToCSIDriver: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
DevicePlugins: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.26
|
||||
|
||||
DisableAcceleratorUsageMetrics: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
DefaultHostNetworkHostPortsInPodTemplates: {Default: false, PreRelease: featuregate.Deprecated},
|
||||
|
||||
DisableCloudProviders: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
DisableKubeletCloudCredentialProviders: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
DownwardAPIHugePages: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in v1.29
|
||||
DevicePluginCDIDevices: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
EndpointSliceTerminatingCondition: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in v1.28
|
||||
DownwardAPIHugePages: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in v1.29
|
||||
|
||||
DynamicResourceAllocation: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -996,9 +1009,9 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update
|
||||
|
||||
ExpandedDNSConfig: {Default: true, PreRelease: featuregate.Beta},
|
||||
ExpandedDNSConfig: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: featuregate.Beta},
|
||||
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
GRPCContainerProbe: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, //remove in 1.29
|
||||
|
||||
@ -1022,37 +1035,45 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
InTreePluginPortworxUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
InTreePluginRBDUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
InTreePluginRBDUnregister: {Default: false, PreRelease: featuregate.Deprecated}, // deprecated in 1.28, remove in 1.31
|
||||
|
||||
InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
IPTablesOwnershipCleanup: {Default: true, PreRelease: featuregate.Beta},
|
||||
IPTablesOwnershipCleanup: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
JobBackoffLimitPerIndex: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
JobPodFailurePolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
JobPodReplacementPolicy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
JobReadyPods: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
JobTrackingWithFinalizers: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
KubeletCredentialProviders: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
KubeletCgroupDriverFromCRI: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletInUserNamespace: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletPodResources: {Default: true, PreRelease: featuregate.Beta},
|
||||
KubeletPodResources: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.28, remove in 1.30
|
||||
|
||||
KubeletPodResourcesDynamicResources: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletPodResourcesGet: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletPodResourcesGetAllocatable: {Default: true, PreRelease: featuregate.Beta},
|
||||
KubeletPodResourcesGetAllocatable: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.28, remove in 1.30
|
||||
|
||||
KubeletTracing: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
KubeProxyDrainingTerminatingNodes: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
LegacyServiceAccountTokenNoAutoGeneration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
LegacyServiceAccountTokenTracking: {Default: true, PreRelease: featuregate.Beta},
|
||||
LegacyServiceAccountTokenTracking: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
LegacyServiceAccountTokenCleanUp: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -1068,43 +1089,41 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
MinDomainsInPodTopologySpread: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
MinimizeIPTablesRestore: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
MixedProtocolLBService: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
MinimizeIPTablesRestore: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
MultiCIDRRangeAllocator: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
MultiCIDRServiceAllocator: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
NetworkPolicyStatus: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
NewVolumeManagerReconstruction: {Default: false, PreRelease: featuregate.Beta}, // disabled for https://github.com/kubernetes/kubernetes/issues/117745
|
||||
NewVolumeManagerReconstruction: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
NodeLogQuery: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.Beta},
|
||||
NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
NodeSwap: {Default: false, PreRelease: featuregate.Alpha},
|
||||
NodeSwap: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
PDBUnhealthyPodEvictionPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PersistentVolumeLastPhaseTransitionTime: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
PodAndContainerStatsFromCRI: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
PodDeletionCost: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PodDisruptionConditions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PodHasNetworkCondition: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PodReadyToStartContainersCondition: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
PodHostIPs: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
PodSchedulingReadiness: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PodSecurity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
|
||||
ProbeTerminationGracePeriod: {Default: true, PreRelease: featuregate.Beta}, // Default to true in beta 1.25
|
||||
ProbeTerminationGracePeriod: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
ProcMountType: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ProxyTerminatingEndpoints: {Default: true, PreRelease: featuregate.Beta},
|
||||
ProxyTerminatingEndpoints: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
QOSReserved: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -1112,21 +1131,21 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
RecoverVolumeExpansionFailure: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
RetroactiveDefaultStorageClass: {Default: true, PreRelease: featuregate.Beta},
|
||||
RetroactiveDefaultStorageClass: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
RotateKubeletServerCertificate: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ElasticIndexedJob: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
SchedulerQueueingHints: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
SeccompDefault: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
SecurityContextDeny: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ServiceIPStaticSubrange: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
ServiceNodePortStaticSubrange: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ServiceInternalTrafficPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
ServiceNodePortStaticSubrange: {Default: false, PreRelease: featuregate.Alpha},
|
||||
SidecarContainers: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
@ -1142,13 +1161,15 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
TopologyManagerPolicyAlphaOptions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
TopologyManagerPolicyBetaOptions: {Default: false, PreRelease: featuregate.Beta},
|
||||
TopologyManagerPolicyBetaOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
TopologyManagerPolicyOptions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
TopologyManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
UnknownVersionInteroperabilityProxy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
UserNamespacesStatelessPodsSupport: {Default: false, PreRelease: featuregate.Alpha},
|
||||
UserNamespacesSupport: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
WinDSR: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -1156,18 +1177,18 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
WindowsHostNetwork: {Default: true, PreRelease: featuregate.Alpha},
|
||||
|
||||
WindowsHostProcessContainers: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
NodeInclusionPolicyInPodTopologySpread: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
SELinuxMountReadWriteOncePod: {Default: false, PreRelease: featuregate.Beta}, // disabled for https://github.com/kubernetes/kubernetes/issues/117745
|
||||
SELinuxMountReadWriteOncePod: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
InPlacePodVerticalScaling: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
PodIndexLabel: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
||||
genericfeatures.AdmissionWebhookMatchConditions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
genericfeatures.AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
@ -1177,14 +1198,10 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
genericfeatures.APIResponseCompression: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.AdvancedAuditing: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
genericfeatures.ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
genericfeatures.ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.DryRun: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.OpenAPIV3: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
@ -1193,6 +1210,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
||||
apiextensionsfeatures.CRDValidationRatcheting: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
// features that enable backwards compatibility but are scheduled to be removed
|
||||
// ...
|
||||
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
9
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/OWNERS
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/OWNERS
generated
vendored
@ -1,9 +0,0 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
# Disable inheritance as this is an api owners file
|
||||
options:
|
||||
no_parent_owners: true
|
||||
approvers:
|
||||
- api-approvers
|
||||
reviewers:
|
||||
- sig-node-api-reviewers
|
20
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/doc.go
generated
vendored
20
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/doc.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=kubelet.config.k8s.io
|
||||
|
||||
package config // import "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
31
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/helpers.go
generated
vendored
31
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/helpers.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
// KubeletConfigurationPathRefs returns pointers to all of the KubeletConfiguration fields that contain filepaths.
|
||||
// You might use this, for example, to resolve all relative paths against some common root before
|
||||
// passing the configuration to the application. This method must be kept up to date as new fields are added.
|
||||
func KubeletConfigurationPathRefs(kc *KubeletConfiguration) []*string {
|
||||
paths := []*string{}
|
||||
paths = append(paths, &kc.StaticPodPath)
|
||||
paths = append(paths, &kc.Authentication.X509.ClientCAFile)
|
||||
paths = append(paths, &kc.TLSCertFile)
|
||||
paths = append(paths, &kc.TLSPrivateKeyFile)
|
||||
paths = append(paths, &kc.ResolverConfig)
|
||||
paths = append(paths, &kc.VolumePluginDir)
|
||||
return paths
|
||||
}
|
45
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/register.go
generated
vendored
45
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/register.go
generated
vendored
@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name used in this package
|
||||
const GroupName = "kubelet.config.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
var (
|
||||
// SchemeBuilder is the scheme builder with scheme init functions to run for this API package
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme is a global function that registers this API group & version to a scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// addKnownTypes registers known types to the given scheme
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&KubeletConfiguration{},
|
||||
&SerializedNodeConfigSource{},
|
||||
&CredentialProviderConfig{},
|
||||
)
|
||||
return nil
|
||||
}
|
661
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go
generated
vendored
661
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go
generated
vendored
@ -1,661 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
logsapi "k8s.io/component-base/logs/api/v1"
|
||||
tracingapi "k8s.io/component-base/tracing/api/v1"
|
||||
)
|
||||
|
||||
// HairpinMode denotes how the kubelet should configure networking to handle
|
||||
// hairpin packets.
|
||||
type HairpinMode string
|
||||
|
||||
// Enum settings for different ways to handle hairpin packets.
|
||||
const (
|
||||
// Set the hairpin flag on the veth of containers in the respective
|
||||
// container runtime.
|
||||
HairpinVeth = "hairpin-veth"
|
||||
// Make the container bridge promiscuous. This will force it to accept
|
||||
// hairpin packets, even if the flag isn't set on ports of the bridge.
|
||||
PromiscuousBridge = "promiscuous-bridge"
|
||||
// Neither of the above. If the kubelet is started in this hairpin mode
|
||||
// and kube-proxy is running in iptables mode, hairpin packets will be
|
||||
// dropped by the container bridge.
|
||||
HairpinNone = "none"
|
||||
)
|
||||
|
||||
// ResourceChangeDetectionStrategy denotes a mode in which internal
|
||||
// managers (secret, configmap) are discovering object changes.
|
||||
type ResourceChangeDetectionStrategy string
|
||||
|
||||
// Enum settings for different strategies of kubelet managers.
|
||||
const (
|
||||
// GetChangeDetectionStrategy is a mode in which kubelet fetches
|
||||
// necessary objects directly from apiserver.
|
||||
GetChangeDetectionStrategy ResourceChangeDetectionStrategy = "Get"
|
||||
// TTLCacheChangeDetectionStrategy is a mode in which kubelet uses
|
||||
// ttl cache for object directly fetched from apiserver.
|
||||
TTLCacheChangeDetectionStrategy ResourceChangeDetectionStrategy = "Cache"
|
||||
// WatchChangeDetectionStrategy is a mode in which kubelet uses
|
||||
// watches to observe changes to objects that are in its interest.
|
||||
WatchChangeDetectionStrategy ResourceChangeDetectionStrategy = "Watch"
|
||||
// RestrictedTopologyManagerPolicy is a mode in which kubelet only allows
|
||||
// pods with optimal NUMA node alignment for requested resources
|
||||
RestrictedTopologyManagerPolicy = "restricted"
|
||||
// BestEffortTopologyManagerPolicy is a mode in which kubelet will favour
|
||||
// pods with NUMA alignment of CPU and device resources.
|
||||
BestEffortTopologyManagerPolicy = "best-effort"
|
||||
// NoneTopologyManagerPolicy is a mode in which kubelet has no knowledge
|
||||
// of NUMA alignment of a pod's CPU and device resources.
|
||||
NoneTopologyManagerPolicy = "none"
|
||||
// SingleNumaNodeTopologyManagerPolicy is a mode in which kubelet only allows
|
||||
// pods with a single NUMA alignment of CPU and device resources.
|
||||
SingleNumaNodeTopologyManagerPolicy = "single-numa-node"
|
||||
// ContainerTopologyManagerScope represents that
|
||||
// topology policy is applied on a per-container basis.
|
||||
ContainerTopologyManagerScope = "container"
|
||||
// PodTopologyManagerScope represents that
|
||||
// topology policy is applied on a per-pod basis.
|
||||
PodTopologyManagerScope = "pod"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// KubeletConfiguration contains the configuration for the Kubelet
|
||||
type KubeletConfiguration struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// enableServer enables Kubelet's secured server.
|
||||
// Note: Kubelet's insecure port is controlled by the readOnlyPort option.
|
||||
EnableServer bool
|
||||
// staticPodPath is the path to the directory containing local (static) pods to
|
||||
// run, or the path to a single static pod file.
|
||||
StaticPodPath string
|
||||
// syncFrequency is the max period between synchronizing running
|
||||
// containers and config
|
||||
SyncFrequency metav1.Duration
|
||||
// fileCheckFrequency is the duration between checking config files for
|
||||
// new data
|
||||
FileCheckFrequency metav1.Duration
|
||||
// httpCheckFrequency is the duration between checking http for new data
|
||||
HTTPCheckFrequency metav1.Duration
|
||||
// staticPodURL is the URL for accessing static pods to run
|
||||
StaticPodURL string
|
||||
// staticPodURLHeader is a map of slices with HTTP headers to use when accessing the podURL
|
||||
StaticPodURLHeader map[string][]string `datapolicy:"token"`
|
||||
// address is the IP address for the Kubelet to serve on (set to 0.0.0.0
|
||||
// for all interfaces)
|
||||
Address string
|
||||
// port is the port for the Kubelet to serve on.
|
||||
Port int32
|
||||
// readOnlyPort is the read-only port for the Kubelet to serve on with
|
||||
// no authentication/authorization (set to 0 to disable)
|
||||
ReadOnlyPort int32
|
||||
// volumePluginDir is the full path of the directory in which to search
|
||||
// for additional third party volume plugins.
|
||||
VolumePluginDir string
|
||||
// providerID, if set, sets the unique id of the instance that an external provider (i.e. cloudprovider)
|
||||
// can use to identify a specific node
|
||||
ProviderID string
|
||||
// tlsCertFile is the file containing x509 Certificate for HTTPS. (CA cert,
|
||||
// if any, concatenated after server cert). If tlsCertFile and
|
||||
// tlsPrivateKeyFile are not provided, a self-signed certificate
|
||||
// and key are generated for the public address and saved to the directory
|
||||
// passed to the Kubelet's --cert-dir flag.
|
||||
TLSCertFile string
|
||||
// tlsPrivateKeyFile is the file containing x509 private key matching tlsCertFile
|
||||
TLSPrivateKeyFile string
|
||||
// TLSCipherSuites is the list of allowed cipher suites for the server.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
TLSCipherSuites []string
|
||||
// TLSMinVersion is the minimum TLS version supported.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
TLSMinVersion string
|
||||
// rotateCertificates enables client certificate rotation. The Kubelet will request a
|
||||
// new certificate from the certificates.k8s.io API. This requires an approver to approve the
|
||||
// certificate signing requests.
|
||||
RotateCertificates bool
|
||||
// serverTLSBootstrap enables server certificate bootstrap. Instead of self
|
||||
// signing a serving certificate, the Kubelet will request a certificate from
|
||||
// the certificates.k8s.io API. This requires an approver to approve the
|
||||
// certificate signing requests. The RotateKubeletServerCertificate feature
|
||||
// must be enabled.
|
||||
ServerTLSBootstrap bool
|
||||
// authentication specifies how requests to the Kubelet's server are authenticated
|
||||
Authentication KubeletAuthentication
|
||||
// authorization specifies how requests to the Kubelet's server are authorized
|
||||
Authorization KubeletAuthorization
|
||||
// registryPullQPS is the limit of registry pulls per second.
|
||||
// Set to 0 for no limit.
|
||||
RegistryPullQPS int32
|
||||
// registryBurst is the maximum size of bursty pulls, temporarily allows
|
||||
// pulls to burst to this number, while still not exceeding registryPullQPS.
|
||||
// Only used if registryPullQPS > 0.
|
||||
RegistryBurst int32
|
||||
// eventRecordQPS is the maximum event creations per second. If 0, there
|
||||
// is no limit enforced.
|
||||
EventRecordQPS int32
|
||||
// eventBurst is the maximum size of a burst of event creations, temporarily
|
||||
// allows event creations to burst to this number, while still not exceeding
|
||||
// eventRecordQPS. Only used if eventRecordQPS > 0.
|
||||
EventBurst int32
|
||||
// enableDebuggingHandlers enables server endpoints for log collection
|
||||
// and local running of containers and commands
|
||||
EnableDebuggingHandlers bool
|
||||
// enableContentionProfiling enables block profiling, if enableDebuggingHandlers is true.
|
||||
EnableContentionProfiling bool
|
||||
// healthzPort is the port of the localhost healthz endpoint (set to 0 to disable)
|
||||
HealthzPort int32
|
||||
// healthzBindAddress is the IP address for the healthz server to serve on
|
||||
HealthzBindAddress string
|
||||
// oomScoreAdj is The oom-score-adj value for kubelet process. Values
|
||||
// must be within the range [-1000, 1000].
|
||||
OOMScoreAdj int32
|
||||
// clusterDomain is the DNS domain for this cluster. If set, kubelet will
|
||||
// configure all containers to search this domain in addition to the
|
||||
// host's search domains.
|
||||
ClusterDomain string
|
||||
// clusterDNS is a list of IP addresses for a cluster DNS server. If set,
|
||||
// kubelet will configure all containers to use this for DNS resolution
|
||||
// instead of the host's DNS servers.
|
||||
ClusterDNS []string
|
||||
// streamingConnectionIdleTimeout is the maximum time a streaming connection
|
||||
// can be idle before the connection is automatically closed.
|
||||
StreamingConnectionIdleTimeout metav1.Duration
|
||||
// nodeStatusUpdateFrequency is the frequency that kubelet computes node
|
||||
// status. If node lease feature is not enabled, it is also the frequency that
|
||||
// kubelet posts node status to master. In that case, be cautious when
|
||||
// changing the constant, it must work with nodeMonitorGracePeriod in nodecontroller.
|
||||
NodeStatusUpdateFrequency metav1.Duration
|
||||
// nodeStatusReportFrequency is the frequency that kubelet posts node
|
||||
// status to master if node status does not change. Kubelet will ignore this
|
||||
// frequency and post node status immediately if any change is detected. It is
|
||||
// only used when node lease feature is enabled.
|
||||
NodeStatusReportFrequency metav1.Duration
|
||||
// nodeLeaseDurationSeconds is the duration the Kubelet will set on its corresponding Lease.
|
||||
NodeLeaseDurationSeconds int32
|
||||
// imageMinimumGCAge is the minimum age for an unused image before it is
|
||||
// garbage collected.
|
||||
ImageMinimumGCAge metav1.Duration
|
||||
// imageGCHighThresholdPercent is the percent of disk usage after which
|
||||
// image garbage collection is always run. The percent is calculated as
|
||||
// this field value out of 100.
|
||||
ImageGCHighThresholdPercent int32
|
||||
// imageGCLowThresholdPercent is the percent of disk usage before which
|
||||
// image garbage collection is never run. Lowest disk usage to garbage
|
||||
// collect to. The percent is calculated as this field value out of 100.
|
||||
ImageGCLowThresholdPercent int32
|
||||
// How frequently to calculate and cache volume disk usage for all pods
|
||||
VolumeStatsAggPeriod metav1.Duration
|
||||
// KubeletCgroups is the absolute name of cgroups to isolate the kubelet in
|
||||
KubeletCgroups string
|
||||
// SystemCgroups is absolute name of cgroups in which to place
|
||||
// all non-kernel processes that are not already in a container. Empty
|
||||
// for no container. Rolling back the flag requires a reboot.
|
||||
SystemCgroups string
|
||||
// CgroupRoot is the root cgroup to use for pods.
|
||||
// If CgroupsPerQOS is enabled, this is the root of the QoS cgroup hierarchy.
|
||||
CgroupRoot string
|
||||
// Enable QoS based Cgroup hierarchy: top level cgroups for QoS Classes
|
||||
// And all Burstable and BestEffort pods are brought up under their
|
||||
// specific top level QoS cgroup.
|
||||
CgroupsPerQOS bool
|
||||
// driver that the kubelet uses to manipulate cgroups on the host (cgroupfs or systemd)
|
||||
CgroupDriver string
|
||||
// CPUManagerPolicy is the name of the policy to use.
|
||||
// Requires the CPUManager feature gate to be enabled.
|
||||
CPUManagerPolicy string
|
||||
// CPUManagerPolicyOptions is a set of key=value which allows to set extra options
|
||||
// to fine tune the behaviour of the cpu manager policies.
|
||||
// Requires both the "CPUManager" and "CPUManagerPolicyOptions" feature gates to be enabled.
|
||||
CPUManagerPolicyOptions map[string]string
|
||||
// CPU Manager reconciliation period.
|
||||
// Requires the CPUManager feature gate to be enabled.
|
||||
CPUManagerReconcilePeriod metav1.Duration
|
||||
// MemoryManagerPolicy is the name of the policy to use.
|
||||
// Requires the MemoryManager feature gate to be enabled.
|
||||
MemoryManagerPolicy string
|
||||
// TopologyManagerPolicy is the name of the policy to use.
|
||||
TopologyManagerPolicy string
|
||||
// TopologyManagerScope represents the scope of topology hint generation
|
||||
// that topology manager requests and hint providers generate.
|
||||
// Default: "container"
|
||||
// +optional
|
||||
TopologyManagerScope string
|
||||
// TopologyManagerPolicyOptions is a set of key=value which allows to set extra options
|
||||
// to fine tune the behaviour of the topology manager policies.
|
||||
// Requires both the "TopologyManager" and "TopologyManagerPolicyOptions" feature gates to be enabled.
|
||||
TopologyManagerPolicyOptions map[string]string
|
||||
// Map of QoS resource reservation percentages (memory only for now).
|
||||
// Requires the QOSReserved feature gate to be enabled.
|
||||
QOSReserved map[string]string
|
||||
// runtimeRequestTimeout is the timeout for all runtime requests except long running
|
||||
// requests - pull, logs, exec and attach.
|
||||
RuntimeRequestTimeout metav1.Duration
|
||||
// hairpinMode specifies how the Kubelet should configure the container
|
||||
// bridge for hairpin packets.
|
||||
// Setting this flag allows endpoints in a Service to loadbalance back to
|
||||
// themselves if they should try to access their own Service. Values:
|
||||
// "promiscuous-bridge": make the container bridge promiscuous.
|
||||
// "hairpin-veth": set the hairpin flag on container veth interfaces.
|
||||
// "none": do nothing.
|
||||
// Generally, one must set --hairpin-mode=hairpin-veth to achieve hairpin NAT,
|
||||
// because promiscuous-bridge assumes the existence of a container bridge named cbr0.
|
||||
HairpinMode string
|
||||
// maxPods is the number of pods that can run on this Kubelet.
|
||||
MaxPods int32
|
||||
// The CIDR to use for pod IP addresses, only used in standalone mode.
|
||||
// In cluster mode, this is obtained from the master.
|
||||
PodCIDR string
|
||||
// The maximum number of processes per pod. If -1, the kubelet defaults to the node allocatable pid capacity.
|
||||
PodPidsLimit int64
|
||||
// ResolverConfig is the resolver configuration file used as the basis
|
||||
// for the container DNS resolution configuration.
|
||||
ResolverConfig string
|
||||
// RunOnce causes the Kubelet to check the API server once for pods,
|
||||
// run those in addition to the pods specified by static pod files, and exit.
|
||||
RunOnce bool
|
||||
// cpuCFSQuota enables CPU CFS quota enforcement for containers that
|
||||
// specify CPU limits
|
||||
CPUCFSQuota bool
|
||||
// CPUCFSQuotaPeriod sets the CPU CFS quota period value, cpu.cfs_period_us, defaults to 100ms
|
||||
CPUCFSQuotaPeriod metav1.Duration
|
||||
// maxOpenFiles is Number of files that can be opened by Kubelet process.
|
||||
MaxOpenFiles int64
|
||||
// nodeStatusMaxImages caps the number of images reported in Node.Status.Images.
|
||||
NodeStatusMaxImages int32
|
||||
// contentType is contentType of requests sent to apiserver.
|
||||
ContentType string
|
||||
// kubeAPIQPS is the QPS to use while talking with kubernetes apiserver
|
||||
KubeAPIQPS int32
|
||||
// kubeAPIBurst is the burst to allow while talking with kubernetes
|
||||
// apiserver
|
||||
KubeAPIBurst int32
|
||||
// serializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
|
||||
SerializeImagePulls bool
|
||||
// MaxParallelImagePulls sets the maximum number of image pulls in parallel.
|
||||
MaxParallelImagePulls *int32
|
||||
// Map of signal names to quantities that defines hard eviction thresholds. For example: {"memory.available": "300Mi"}.
|
||||
// Some default signals are Linux only: nodefs.inodesFree
|
||||
EvictionHard map[string]string
|
||||
// Map of signal names to quantities that defines soft eviction thresholds. For example: {"memory.available": "300Mi"}.
|
||||
EvictionSoft map[string]string
|
||||
// Map of signal names to quantities that defines grace periods for each soft eviction signal. For example: {"memory.available": "30s"}.
|
||||
EvictionSoftGracePeriod map[string]string
|
||||
// Duration for which the kubelet has to wait before transitioning out of an eviction pressure condition.
|
||||
EvictionPressureTransitionPeriod metav1.Duration
|
||||
// Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met.
|
||||
EvictionMaxPodGracePeriod int32
|
||||
// Map of signal names to quantities that defines minimum reclaims, which describe the minimum
|
||||
// amount of a given resource the kubelet will reclaim when performing a pod eviction while
|
||||
// that resource is under pressure. For example: {"imagefs.available": "2Gi"}
|
||||
EvictionMinimumReclaim map[string]string
|
||||
// podsPerCore is the maximum number of pods per core. Cannot exceed MaxPods.
|
||||
// If 0, this field is ignored.
|
||||
PodsPerCore int32
|
||||
// enableControllerAttachDetach enables the Attach/Detach controller to
|
||||
// manage attachment/detachment of volumes scheduled to this node, and
|
||||
// disables kubelet from executing any attach/detach operations
|
||||
EnableControllerAttachDetach bool
|
||||
// protectKernelDefaults, if true, causes the Kubelet to error if kernel
|
||||
// flags are not as it expects. Otherwise the Kubelet will attempt to modify
|
||||
// kernel flags to match its expectation.
|
||||
ProtectKernelDefaults bool
|
||||
// If true, Kubelet ensures a set of iptables rules are present on host.
|
||||
// These rules will serve as utility for various components, e.g. kube-proxy.
|
||||
// The rules will be created based on IPTablesMasqueradeBit and IPTablesDropBit.
|
||||
MakeIPTablesUtilChains bool
|
||||
// iptablesMasqueradeBit is the bit of the iptables fwmark space to mark for SNAT
|
||||
// Values must be within the range [0, 31]. Must be different from other mark bits.
|
||||
// Warning: Please match the value of the corresponding parameter in kube-proxy.
|
||||
// TODO: clean up IPTablesMasqueradeBit in kube-proxy
|
||||
IPTablesMasqueradeBit int32
|
||||
// iptablesDropBit is the bit of the iptables fwmark space to mark for dropping packets.
|
||||
// Values must be within the range [0, 31]. Must be different from other mark bits.
|
||||
IPTablesDropBit int32
|
||||
// featureGates is a map of feature names to bools that enable or disable alpha/experimental
|
||||
// features. This field modifies piecemeal the built-in default values from
|
||||
// "k8s.io/kubernetes/pkg/features/kube_features.go".
|
||||
FeatureGates map[string]bool
|
||||
// Tells the Kubelet to fail to start if swap is enabled on the node.
|
||||
FailSwapOn bool
|
||||
// memorySwap configures swap memory available to container workloads.
|
||||
// +featureGate=NodeSwap
|
||||
// +optional
|
||||
MemorySwap MemorySwapConfiguration
|
||||
// A quantity defines the maximum size of the container log file before it is rotated. For example: "5Mi" or "256Ki".
|
||||
ContainerLogMaxSize string
|
||||
// Maximum number of container log files that can be present for a container.
|
||||
ContainerLogMaxFiles int32
|
||||
// ConfigMapAndSecretChangeDetectionStrategy is a mode in which config map and secret managers are running.
|
||||
ConfigMapAndSecretChangeDetectionStrategy ResourceChangeDetectionStrategy
|
||||
// A comma separated allowlist of unsafe sysctls or sysctl patterns (ending in `*`).
|
||||
// Unsafe sysctl groups are `kernel.shm*`, `kernel.msg*`, `kernel.sem`, `fs.mqueue.*`, and `net.*`.
|
||||
// These sysctls are namespaced but not allowed by default.
|
||||
// For example: "`kernel.msg*,net.ipv4.route.min_pmtu`"
|
||||
// +optional
|
||||
AllowedUnsafeSysctls []string
|
||||
// kernelMemcgNotification if enabled, the kubelet will integrate with the kernel memcg
|
||||
// notification to determine if memory eviction thresholds are crossed rather than polling.
|
||||
KernelMemcgNotification bool
|
||||
|
||||
/* the following fields are meant for Node Allocatable */
|
||||
|
||||
// A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=150G,ephemeral-storage=1G,pid=100) pairs
|
||||
// that describe resources reserved for non-kubernetes components.
|
||||
// Currently only cpu, memory and local ephemeral storage for root file system are supported.
|
||||
// See http://kubernetes.io/docs/user-guide/compute-resources for more detail.
|
||||
SystemReserved map[string]string
|
||||
// A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=150G,ephemeral-storage=1G,pid=100) pairs
|
||||
// that describe resources reserved for kubernetes system components.
|
||||
// Currently only cpu, memory and local ephemeral storage for root file system are supported.
|
||||
// See http://kubernetes.io/docs/user-guide/compute-resources for more detail.
|
||||
KubeReserved map[string]string
|
||||
// This flag helps kubelet identify absolute name of top level cgroup used to enforce `SystemReserved` compute resource reservation for OS system daemons.
|
||||
// Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information.
|
||||
SystemReservedCgroup string
|
||||
// This flag helps kubelet identify absolute name of top level cgroup used to enforce `KubeReserved` compute resource reservation for Kubernetes node system daemons.
|
||||
// Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information.
|
||||
KubeReservedCgroup string
|
||||
// This flag specifies the various Node Allocatable enforcements that Kubelet needs to perform.
|
||||
// This flag accepts a list of options. Acceptable options are `pods`, `system-reserved` & `kube-reserved`.
|
||||
// Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information.
|
||||
EnforceNodeAllocatable []string
|
||||
// This option specifies the cpu list reserved for the host level system threads and kubernetes related threads.
|
||||
// This provide a "static" CPU list rather than the "dynamic" list by system-reserved and kube-reserved.
|
||||
// This option overwrites CPUs provided by system-reserved and kube-reserved.
|
||||
ReservedSystemCPUs string
|
||||
// The previous version for which you want to show hidden metrics.
|
||||
// Only the previous minor version is meaningful, other values will not be allowed.
|
||||
// The format is <major>.<minor>, e.g.: '1.16'.
|
||||
// The purpose of this format is make sure you have the opportunity to notice if the next release hides additional metrics,
|
||||
// rather than being surprised when they are permanently removed in the release after that.
|
||||
ShowHiddenMetricsForVersion string
|
||||
// Logging specifies the options of logging.
|
||||
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information.
|
||||
Logging logsapi.LoggingConfiguration
|
||||
// EnableSystemLogHandler enables /logs handler.
|
||||
EnableSystemLogHandler bool
|
||||
// EnableSystemLogQuery enables the node log query feature on the /logs endpoint.
|
||||
// EnableSystemLogHandler has to be enabled in addition for this feature to work.
|
||||
// +featureGate=NodeLogQuery
|
||||
// +optional
|
||||
EnableSystemLogQuery bool
|
||||
// ShutdownGracePeriod specifies the total duration that the node should delay the shutdown and total grace period for pod termination during a node shutdown.
|
||||
// Defaults to 0 seconds.
|
||||
// +featureGate=GracefulNodeShutdown
|
||||
// +optional
|
||||
ShutdownGracePeriod metav1.Duration
|
||||
// ShutdownGracePeriodCriticalPods specifies the duration used to terminate critical pods during a node shutdown. This should be less than ShutdownGracePeriod.
|
||||
// Defaults to 0 seconds.
|
||||
// For example, if ShutdownGracePeriod=30s, and ShutdownGracePeriodCriticalPods=10s, during a node shutdown the first 20 seconds would be reserved for gracefully terminating normal pods, and the last 10 seconds would be reserved for terminating critical pods.
|
||||
// +featureGate=GracefulNodeShutdown
|
||||
// +optional
|
||||
ShutdownGracePeriodCriticalPods metav1.Duration
|
||||
// ShutdownGracePeriodByPodPriority specifies the shutdown grace period for Pods based
|
||||
// on their associated priority class value.
|
||||
// When a shutdown request is received, the Kubelet will initiate shutdown on all pods
|
||||
// running on the node with a grace period that depends on the priority of the pod,
|
||||
// and then wait for all pods to exit.
|
||||
// Each entry in the array represents the graceful shutdown time a pod with a priority
|
||||
// class value that lies in the range of that value and the next higher entry in the
|
||||
// list when the node is shutting down.
|
||||
ShutdownGracePeriodByPodPriority []ShutdownGracePeriodByPodPriority
|
||||
// ReservedMemory specifies a comma-separated list of memory reservations for NUMA nodes.
|
||||
// The parameter makes sense only in the context of the memory manager feature. The memory manager will not allocate reserved memory for container workloads.
|
||||
// For example, if you have a NUMA0 with 10Gi of memory and the ReservedMemory was specified to reserve 1Gi of memory at NUMA0,
|
||||
// the memory manager will assume that only 9Gi is available for allocation.
|
||||
// You can specify a different amount of NUMA node and memory types.
|
||||
// You can omit this parameter at all, but you should be aware that the amount of reserved memory from all NUMA nodes
|
||||
// should be equal to the amount of memory specified by the node allocatable features(https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
// If at least one node allocatable parameter has a non-zero value, you will need to specify at least one NUMA node.
|
||||
// Also, avoid specifying:
|
||||
// 1. Duplicates, the same NUMA node, and memory type, but with a different value.
|
||||
// 2. zero limits for any memory type.
|
||||
// 3. NUMAs nodes IDs that do not exist under the machine.
|
||||
// 4. memory types except for memory and hugepages-<size>
|
||||
ReservedMemory []MemoryReservation
|
||||
// EnableProfiling enables /debug/pprof handler.
|
||||
EnableProfilingHandler bool
|
||||
// EnableDebugFlagsHandler enables/debug/flags/v handler.
|
||||
EnableDebugFlagsHandler bool
|
||||
// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||
SeccompDefault bool
|
||||
// MemoryThrottlingFactor specifies the factor multiplied by the memory limit or node allocatable memory
|
||||
// when setting the cgroupv2 memory.high value to enforce MemoryQoS.
|
||||
// Decreasing this factor will set lower high limit for container cgroups and put heavier reclaim pressure
|
||||
// while increasing will put less reclaim pressure.
|
||||
// See https://kep.k8s.io/2570 for more details.
|
||||
// Default: 0.9
|
||||
// +featureGate=MemoryQoS
|
||||
// +optional
|
||||
MemoryThrottlingFactor *float64
|
||||
// registerWithTaints are an array of taints to add to a node object when
|
||||
// the kubelet registers itself. This only takes effect when registerNode
|
||||
// is true and upon the initial registration of the node.
|
||||
// +optional
|
||||
RegisterWithTaints []v1.Taint
|
||||
// registerNode enables automatic registration with the apiserver.
|
||||
// +optional
|
||||
RegisterNode bool
|
||||
|
||||
// Tracing specifies the versioned configuration for OpenTelemetry tracing clients.
|
||||
// See https://kep.k8s.io/2832 for more details.
|
||||
// +featureGate=KubeletTracing
|
||||
// +optional
|
||||
Tracing *tracingapi.TracingConfiguration
|
||||
|
||||
// LocalStorageCapacityIsolation enables local ephemeral storage isolation feature. The default setting is true.
|
||||
// This feature allows users to set request/limit for container's ephemeral storage and manage it in a similar way
|
||||
// as cpu and memory. It also allows setting sizeLimit for emptyDir volume, which will trigger pod eviction if disk
|
||||
// usage from the volume exceeds the limit.
|
||||
// This feature depends on the capability of detecting correct root file system disk usage. For certain systems,
|
||||
// such as kind rootless, if this capability cannot be supported, the feature LocalStorageCapacityIsolation should be
|
||||
// disabled. Once disabled, user should not set request/limit for container's ephemeral storage, or sizeLimit for emptyDir.
|
||||
// +optional
|
||||
LocalStorageCapacityIsolation bool
|
||||
|
||||
// ContainerRuntimeEndpoint is the endpoint of container runtime.
|
||||
// unix domain sockets supported on Linux while npipes and tcp endpoints are supported for windows.
|
||||
// Examples:'unix:///path/to/runtime.sock', 'npipe:////./pipe/runtime'
|
||||
ContainerRuntimeEndpoint string
|
||||
|
||||
// ImageServiceEndpoint is the endpoint of container image service.
|
||||
// If not specified the default value is ContainerRuntimeEndpoint
|
||||
// +optional
|
||||
ImageServiceEndpoint string
|
||||
}
|
||||
|
||||
// KubeletAuthorizationMode denotes the authorization mode for the kubelet
|
||||
type KubeletAuthorizationMode string
|
||||
|
||||
const (
|
||||
// KubeletAuthorizationModeAlwaysAllow authorizes all authenticated requests
|
||||
KubeletAuthorizationModeAlwaysAllow KubeletAuthorizationMode = "AlwaysAllow"
|
||||
// KubeletAuthorizationModeWebhook uses the SubjectAccessReview API to determine authorization
|
||||
KubeletAuthorizationModeWebhook KubeletAuthorizationMode = "Webhook"
|
||||
)
|
||||
|
||||
// KubeletAuthorization holds the state related to the authorization in the kublet.
|
||||
type KubeletAuthorization struct {
|
||||
// mode is the authorization mode to apply to requests to the kubelet server.
|
||||
// Valid values are AlwaysAllow and Webhook.
|
||||
// Webhook mode uses the SubjectAccessReview API to determine authorization.
|
||||
Mode KubeletAuthorizationMode
|
||||
|
||||
// webhook contains settings related to Webhook authorization.
|
||||
Webhook KubeletWebhookAuthorization
|
||||
}
|
||||
|
||||
// KubeletWebhookAuthorization holds the state related to the Webhook
|
||||
// Authorization in the Kubelet.
|
||||
type KubeletWebhookAuthorization struct {
|
||||
// cacheAuthorizedTTL is the duration to cache 'authorized' responses from the webhook authorizer.
|
||||
CacheAuthorizedTTL metav1.Duration
|
||||
// cacheUnauthorizedTTL is the duration to cache 'unauthorized' responses from the webhook authorizer.
|
||||
CacheUnauthorizedTTL metav1.Duration
|
||||
}
|
||||
|
||||
// KubeletAuthentication holds the Kubetlet Authentication setttings.
|
||||
type KubeletAuthentication struct {
|
||||
// x509 contains settings related to x509 client certificate authentication
|
||||
X509 KubeletX509Authentication
|
||||
// webhook contains settings related to webhook bearer token authentication
|
||||
Webhook KubeletWebhookAuthentication
|
||||
// anonymous contains settings related to anonymous authentication
|
||||
Anonymous KubeletAnonymousAuthentication
|
||||
}
|
||||
|
||||
// KubeletX509Authentication contains settings related to x509 client certificate authentication
|
||||
type KubeletX509Authentication struct {
|
||||
// clientCAFile is the path to a PEM-encoded certificate bundle. If set, any request presenting a client certificate
|
||||
// signed by one of the authorities in the bundle is authenticated with a username corresponding to the CommonName,
|
||||
// and groups corresponding to the Organization in the client certificate.
|
||||
ClientCAFile string
|
||||
}
|
||||
|
||||
// KubeletWebhookAuthentication contains settings related to webhook authentication
|
||||
type KubeletWebhookAuthentication struct {
|
||||
// enabled allows bearer token authentication backed by the tokenreviews.authentication.k8s.io API
|
||||
Enabled bool
|
||||
// cacheTTL enables caching of authentication results
|
||||
CacheTTL metav1.Duration
|
||||
}
|
||||
|
||||
// KubeletAnonymousAuthentication enables anonymous requests to the kubelet server.
|
||||
type KubeletAnonymousAuthentication struct {
|
||||
// enabled allows anonymous requests to the kubelet server.
|
||||
// Requests that are not rejected by another authentication method are treated as anonymous requests.
|
||||
// Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// SerializedNodeConfigSource allows us to serialize NodeConfigSource
|
||||
// This type is used internally by the Kubelet for tracking checkpointed dynamic configs.
|
||||
// It exists in the kubeletconfig API group because it is classified as a versioned input to the Kubelet.
|
||||
type SerializedNodeConfigSource struct {
|
||||
metav1.TypeMeta
|
||||
// Source is the source that we are serializing
|
||||
// +optional
|
||||
Source v1.NodeConfigSource
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// CredentialProviderConfig is the configuration containing information about
|
||||
// each exec credential provider. Kubelet reads this configuration from disk and enables
|
||||
// each provider as specified by the CredentialProvider type.
|
||||
type CredentialProviderConfig struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// providers is a list of credential provider plugins that will be enabled by the kubelet.
|
||||
// Multiple providers may match against a single image, in which case credentials
|
||||
// from all providers will be returned to the kubelet. If multiple providers are called
|
||||
// for a single image, the results are combined. If providers return overlapping
|
||||
// auth keys, the value from the provider earlier in this list is used.
|
||||
Providers []CredentialProvider
|
||||
}
|
||||
|
||||
// CredentialProvider represents an exec plugin to be invoked by the kubelet. The plugin is only
|
||||
// invoked when an image being pulled matches the images handled by the plugin (see matchImages).
|
||||
type CredentialProvider struct {
|
||||
// name is the required name of the credential provider. It must match the name of the
|
||||
// provider executable as seen by the kubelet. The executable must be in the kubelet's
|
||||
// bin directory (set by the --credential-provider-bin-dir flag).
|
||||
Name string
|
||||
|
||||
// matchImages is a required list of strings used to match against images in order to
|
||||
// determine if this provider should be invoked. If one of the strings matches the
|
||||
// requested image from the kubelet, the plugin will be invoked and given a chance
|
||||
// to provide credentials. Images are expected to contain the registry domain
|
||||
// and URL path.
|
||||
//
|
||||
// Each entry in matchImages is a pattern which can optionally contain a port and a path.
|
||||
// Globs can be used in the domain, but not in the port or the path. Globs are supported
|
||||
// as subdomains like `*.k8s.io` or `k8s.*.io`, and top-level-domains such as `k8s.*`.
|
||||
// Matching partial subdomains like `app*.k8s.io` is also supported. Each glob can only match
|
||||
// a single subdomain segment, so `*.io` does not match *.k8s.io.
|
||||
//
|
||||
// A match exists between an image and a matchImage when all of the below are true:
|
||||
// - Both contain the same number of domain parts and each part matches.
|
||||
// - The URL path of an imageMatch must be a prefix of the target image URL path.
|
||||
// - If the imageMatch contains a port, then the port must match in the image as well.
|
||||
//
|
||||
// Example values of matchImages:
|
||||
// - `123456789.dkr.ecr.us-east-1.amazonaws.com`
|
||||
// - `*.azurecr.io`
|
||||
// - `gcr.io`
|
||||
// - `*.*.registry.io`
|
||||
// - `registry.io:8080/path`
|
||||
MatchImages []string
|
||||
|
||||
// defaultCacheDuration is the default duration the plugin will cache credentials in-memory
|
||||
// if a cache duration is not provided in the plugin response. This field is required.
|
||||
DefaultCacheDuration *metav1.Duration
|
||||
|
||||
// Required input version of the exec CredentialProviderRequest. The returned CredentialProviderResponse
|
||||
// MUST use the same encoding version as the input. Current supported values are:
|
||||
// - credentialprovider.kubelet.k8s.io/v1alpha1
|
||||
// - credentialprovider.kubelet.k8s.io/v1beta1
|
||||
// - credentialprovider.kubelet.k8s.io/v1
|
||||
APIVersion string
|
||||
|
||||
// Arguments to pass to the command when executing it.
|
||||
// +optional
|
||||
Args []string
|
||||
|
||||
// Env defines additional environment variables to expose to the process. These
|
||||
// are unioned with the host's environment, as well as variables client-go uses
|
||||
// to pass argument to the plugin.
|
||||
// +optional
|
||||
Env []ExecEnvVar
|
||||
}
|
||||
|
||||
// ExecEnvVar is used for setting environment variables when executing an exec-based
|
||||
// credential plugin.
|
||||
type ExecEnvVar struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
// MemoryReservation specifies the memory reservation of different types for each NUMA node
|
||||
type MemoryReservation struct {
|
||||
NumaNode int32
|
||||
Limits v1.ResourceList
|
||||
}
|
||||
|
||||
// ShutdownGracePeriodByPodPriority specifies the shutdown grace period for Pods based on their associated priority class value
|
||||
type ShutdownGracePeriodByPodPriority struct {
|
||||
// priority is the priority value associated with the shutdown grace period
|
||||
Priority int32
|
||||
// shutdownGracePeriodSeconds is the shutdown grace period in seconds
|
||||
ShutdownGracePeriodSeconds int64
|
||||
}
|
||||
|
||||
type MemorySwapConfiguration struct {
|
||||
// swapBehavior configures swap memory available to container workloads. May be one of
|
||||
// "", "LimitedSwap": workload combined memory and swap usage cannot exceed pod memory limit
|
||||
// "UnlimitedSwap": workloads can use unlimited swap, up to the allocatable limit.
|
||||
// +featureGate=NodeSwap
|
||||
// +optional
|
||||
SwapBehavior string
|
||||
}
|
479
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
vendored
479
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
vendored
@ -1,479 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
apiv1 "k8s.io/component-base/tracing/api/v1"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialProvider) DeepCopyInto(out *CredentialProvider) {
|
||||
*out = *in
|
||||
if in.MatchImages != nil {
|
||||
in, out := &in.MatchImages, &out.MatchImages
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DefaultCacheDuration != nil {
|
||||
in, out := &in.DefaultCacheDuration, &out.DefaultCacheDuration
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Args != nil {
|
||||
in, out := &in.Args, &out.Args
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Env != nil {
|
||||
in, out := &in.Env, &out.Env
|
||||
*out = make([]ExecEnvVar, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialProvider.
|
||||
func (in *CredentialProvider) DeepCopy() *CredentialProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialProviderConfig) DeepCopyInto(out *CredentialProviderConfig) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Providers != nil {
|
||||
in, out := &in.Providers, &out.Providers
|
||||
*out = make([]CredentialProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialProviderConfig.
|
||||
func (in *CredentialProviderConfig) DeepCopy() *CredentialProviderConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialProviderConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *CredentialProviderConfig) 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 *ExecEnvVar) DeepCopyInto(out *ExecEnvVar) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecEnvVar.
|
||||
func (in *ExecEnvVar) DeepCopy() *ExecEnvVar {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExecEnvVar)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletAnonymousAuthentication) DeepCopyInto(out *KubeletAnonymousAuthentication) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletAnonymousAuthentication.
|
||||
func (in *KubeletAnonymousAuthentication) DeepCopy() *KubeletAnonymousAuthentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletAnonymousAuthentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletAuthentication) DeepCopyInto(out *KubeletAuthentication) {
|
||||
*out = *in
|
||||
out.X509 = in.X509
|
||||
out.Webhook = in.Webhook
|
||||
out.Anonymous = in.Anonymous
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletAuthentication.
|
||||
func (in *KubeletAuthentication) DeepCopy() *KubeletAuthentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletAuthentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletAuthorization) DeepCopyInto(out *KubeletAuthorization) {
|
||||
*out = *in
|
||||
out.Webhook = in.Webhook
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletAuthorization.
|
||||
func (in *KubeletAuthorization) DeepCopy() *KubeletAuthorization {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletAuthorization)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.SyncFrequency = in.SyncFrequency
|
||||
out.FileCheckFrequency = in.FileCheckFrequency
|
||||
out.HTTPCheckFrequency = in.HTTPCheckFrequency
|
||||
if in.StaticPodURLHeader != nil {
|
||||
in, out := &in.StaticPodURLHeader, &out.StaticPodURLHeader
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.TLSCipherSuites != nil {
|
||||
in, out := &in.TLSCipherSuites, &out.TLSCipherSuites
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.Authentication = in.Authentication
|
||||
out.Authorization = in.Authorization
|
||||
if in.ClusterDNS != nil {
|
||||
in, out := &in.ClusterDNS, &out.ClusterDNS
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.StreamingConnectionIdleTimeout = in.StreamingConnectionIdleTimeout
|
||||
out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency
|
||||
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
|
||||
out.ImageMinimumGCAge = in.ImageMinimumGCAge
|
||||
out.VolumeStatsAggPeriod = in.VolumeStatsAggPeriod
|
||||
if in.CPUManagerPolicyOptions != nil {
|
||||
in, out := &in.CPUManagerPolicyOptions, &out.CPUManagerPolicyOptions
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.CPUManagerReconcilePeriod = in.CPUManagerReconcilePeriod
|
||||
if in.TopologyManagerPolicyOptions != nil {
|
||||
in, out := &in.TopologyManagerPolicyOptions, &out.TopologyManagerPolicyOptions
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.QOSReserved != nil {
|
||||
in, out := &in.QOSReserved, &out.QOSReserved
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.RuntimeRequestTimeout = in.RuntimeRequestTimeout
|
||||
out.CPUCFSQuotaPeriod = in.CPUCFSQuotaPeriod
|
||||
if in.MaxParallelImagePulls != nil {
|
||||
in, out := &in.MaxParallelImagePulls, &out.MaxParallelImagePulls
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.EvictionHard != nil {
|
||||
in, out := &in.EvictionHard, &out.EvictionHard
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.EvictionSoft != nil {
|
||||
in, out := &in.EvictionSoft, &out.EvictionSoft
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.EvictionSoftGracePeriod != nil {
|
||||
in, out := &in.EvictionSoftGracePeriod, &out.EvictionSoftGracePeriod
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.EvictionPressureTransitionPeriod = in.EvictionPressureTransitionPeriod
|
||||
if in.EvictionMinimumReclaim != nil {
|
||||
in, out := &in.EvictionMinimumReclaim, &out.EvictionMinimumReclaim
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.FeatureGates != nil {
|
||||
in, out := &in.FeatureGates, &out.FeatureGates
|
||||
*out = make(map[string]bool, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.MemorySwap = in.MemorySwap
|
||||
if in.AllowedUnsafeSysctls != nil {
|
||||
in, out := &in.AllowedUnsafeSysctls, &out.AllowedUnsafeSysctls
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SystemReserved != nil {
|
||||
in, out := &in.SystemReserved, &out.SystemReserved
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.KubeReserved != nil {
|
||||
in, out := &in.KubeReserved, &out.KubeReserved
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.EnforceNodeAllocatable != nil {
|
||||
in, out := &in.EnforceNodeAllocatable, &out.EnforceNodeAllocatable
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Logging.DeepCopyInto(&out.Logging)
|
||||
out.ShutdownGracePeriod = in.ShutdownGracePeriod
|
||||
out.ShutdownGracePeriodCriticalPods = in.ShutdownGracePeriodCriticalPods
|
||||
if in.ShutdownGracePeriodByPodPriority != nil {
|
||||
in, out := &in.ShutdownGracePeriodByPodPriority, &out.ShutdownGracePeriodByPodPriority
|
||||
*out = make([]ShutdownGracePeriodByPodPriority, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ReservedMemory != nil {
|
||||
in, out := &in.ReservedMemory, &out.ReservedMemory
|
||||
*out = make([]MemoryReservation, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.MemoryThrottlingFactor != nil {
|
||||
in, out := &in.MemoryThrottlingFactor, &out.MemoryThrottlingFactor
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
if in.RegisterWithTaints != nil {
|
||||
in, out := &in.RegisterWithTaints, &out.RegisterWithTaints
|
||||
*out = make([]corev1.Taint, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Tracing != nil {
|
||||
in, out := &in.Tracing, &out.Tracing
|
||||
*out = new(apiv1.TracingConfiguration)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletConfiguration.
|
||||
func (in *KubeletConfiguration) DeepCopy() *KubeletConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KubeletConfiguration) 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 *KubeletWebhookAuthentication) DeepCopyInto(out *KubeletWebhookAuthentication) {
|
||||
*out = *in
|
||||
out.CacheTTL = in.CacheTTL
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletWebhookAuthentication.
|
||||
func (in *KubeletWebhookAuthentication) DeepCopy() *KubeletWebhookAuthentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletWebhookAuthentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletWebhookAuthorization) DeepCopyInto(out *KubeletWebhookAuthorization) {
|
||||
*out = *in
|
||||
out.CacheAuthorizedTTL = in.CacheAuthorizedTTL
|
||||
out.CacheUnauthorizedTTL = in.CacheUnauthorizedTTL
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletWebhookAuthorization.
|
||||
func (in *KubeletWebhookAuthorization) DeepCopy() *KubeletWebhookAuthorization {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletWebhookAuthorization)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletX509Authentication) DeepCopyInto(out *KubeletX509Authentication) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletX509Authentication.
|
||||
func (in *KubeletX509Authentication) DeepCopy() *KubeletX509Authentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletX509Authentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MemoryReservation) DeepCopyInto(out *MemoryReservation) {
|
||||
*out = *in
|
||||
if in.Limits != nil {
|
||||
in, out := &in.Limits, &out.Limits
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryReservation.
|
||||
func (in *MemoryReservation) DeepCopy() *MemoryReservation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MemoryReservation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MemorySwapConfiguration) DeepCopyInto(out *MemorySwapConfiguration) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemorySwapConfiguration.
|
||||
func (in *MemorySwapConfiguration) DeepCopy() *MemorySwapConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MemorySwapConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SerializedNodeConfigSource) DeepCopyInto(out *SerializedNodeConfigSource) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.Source.DeepCopyInto(&out.Source)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SerializedNodeConfigSource.
|
||||
func (in *SerializedNodeConfigSource) DeepCopy() *SerializedNodeConfigSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SerializedNodeConfigSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *SerializedNodeConfigSource) 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 *ShutdownGracePeriodByPodPriority) DeepCopyInto(out *ShutdownGracePeriodByPodPriority) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShutdownGracePeriodByPodPriority.
|
||||
func (in *ShutdownGracePeriodByPodPriority) DeepCopy() *ShutdownGracePeriodByPodPriority {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ShutdownGracePeriodByPodPriority)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
41
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
41
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// Pod returns a string representing a pod in a consistent human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func Pod(pod *v1.Pod) string {
|
||||
if pod == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return PodDesc(pod.Name, pod.Namespace, pod.UID)
|
||||
}
|
||||
|
||||
// PodDesc returns a string representing a pod in a consistent human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func PodDesc(podName, podNamespace string, podUID types.UID) string {
|
||||
// Use underscore as the delimiter because it is not allowed in pod name
|
||||
// (DNS subdomain format), while allowed in the container name format.
|
||||
return fmt.Sprintf("%s_%s(%s)", podName, podNamespace, podUID)
|
||||
}
|
64
vendor/k8s.io/kubernetes/pkg/proxy/util/endpoints.go
generated
vendored
64
vendor/k8s.io/kubernetes/pkg/proxy/util/endpoints.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// IPPart returns just the IP part of an IP or IP:port or endpoint string. If the IP
|
||||
// part is an IPv6 address enclosed in brackets (e.g. "[fd00:1::5]:9999"),
|
||||
// then the brackets are stripped as well.
|
||||
func IPPart(s string) string {
|
||||
if ip := netutils.ParseIPSloppy(s); ip != nil {
|
||||
// IP address without port
|
||||
return s
|
||||
}
|
||||
// Must be IP:port
|
||||
host, _, err := net.SplitHostPort(s)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to parse host-port", "input", s)
|
||||
return ""
|
||||
}
|
||||
// Check if host string is a valid IP address
|
||||
ip := netutils.ParseIPSloppy(host)
|
||||
if ip == nil {
|
||||
klog.ErrorS(nil, "Failed to parse IP", "input", host)
|
||||
return ""
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
|
||||
// PortPart returns just the port part of an endpoint string.
|
||||
func PortPart(s string) (int, error) {
|
||||
// Must be IP:port
|
||||
_, port, err := net.SplitHostPort(s)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to parse host-port", "input", s)
|
||||
return -1, err
|
||||
}
|
||||
portNumber, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to parse port", "input", port)
|
||||
return -1, err
|
||||
}
|
||||
return portNumber, nil
|
||||
}
|
39
vendor/k8s.io/kubernetes/pkg/proxy/util/network.go
generated
vendored
39
vendor/k8s.io/kubernetes/pkg/proxy/util/network.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// NetworkInterfacer defines an interface for several net library functions. Production
|
||||
// code will forward to net library functions, and unit tests will override the methods
|
||||
// for testing purposes.
|
||||
type NetworkInterfacer interface {
|
||||
InterfaceAddrs() ([]net.Addr, error)
|
||||
}
|
||||
|
||||
// RealNetwork implements the NetworkInterfacer interface for production code, just
|
||||
// wrapping the underlying net library function calls.
|
||||
type RealNetwork struct{}
|
||||
|
||||
// InterfaceAddrs wraps net.InterfaceAddrs(), it's a part of NetworkInterfacer interface.
|
||||
func (RealNetwork) InterfaceAddrs() ([]net.Addr, error) {
|
||||
return net.InterfaceAddrs()
|
||||
}
|
||||
|
||||
var _ NetworkInterfacer = &RealNetwork{}
|
127
vendor/k8s.io/kubernetes/pkg/proxy/util/nodeport_addresses.go
generated
vendored
127
vendor/k8s.io/kubernetes/pkg/proxy/util/nodeport_addresses.go
generated
vendored
@ -1,127 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// NodePortAddresses is used to handle the --nodeport-addresses flag
|
||||
type NodePortAddresses struct {
|
||||
cidrStrings []string
|
||||
|
||||
cidrs []*net.IPNet
|
||||
containsIPv4Loopback bool
|
||||
}
|
||||
|
||||
// RFC 5735 127.0.0.0/8 - This block is assigned for use as the Internet host loopback address
|
||||
var ipv4LoopbackStart = net.IPv4(127, 0, 0, 0)
|
||||
|
||||
// NewNodePortAddresses takes the `--nodeport-addresses` value (which is assumed to
|
||||
// contain only valid CIDRs) and returns a NodePortAddresses object. If cidrStrings is
|
||||
// empty, this is treated as `["0.0.0.0/0", "::/0"]`.
|
||||
func NewNodePortAddresses(cidrStrings []string) *NodePortAddresses {
|
||||
if len(cidrStrings) == 0 {
|
||||
cidrStrings = []string{IPv4ZeroCIDR, IPv6ZeroCIDR}
|
||||
}
|
||||
|
||||
npa := &NodePortAddresses{
|
||||
cidrStrings: cidrStrings,
|
||||
}
|
||||
|
||||
for _, str := range npa.cidrStrings {
|
||||
_, cidr, _ := netutils.ParseCIDRSloppy(str)
|
||||
npa.cidrs = append(npa.cidrs, cidr)
|
||||
|
||||
if netutils.IsIPv4CIDR(cidr) {
|
||||
if cidr.IP.IsLoopback() || cidr.Contains(ipv4LoopbackStart) {
|
||||
npa.containsIPv4Loopback = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return npa
|
||||
}
|
||||
|
||||
func (npa *NodePortAddresses) String() string {
|
||||
return fmt.Sprintf("%v", npa.cidrStrings)
|
||||
}
|
||||
|
||||
// GetNodeAddresses return all matched node IP addresses for npa's CIDRs.
|
||||
// If npa's CIDRs include "0.0.0.0/0" and/or "::/0", then those values will be returned
|
||||
// verbatim in the response and no actual IPs of that family will be returned.
|
||||
// If no matching IPs are found, GetNodeAddresses will return an error.
|
||||
// NetworkInterfacer is injected for test purpose.
|
||||
func (npa *NodePortAddresses) GetNodeAddresses(nw NetworkInterfacer) (sets.String, error) {
|
||||
uniqueAddressList := sets.NewString()
|
||||
|
||||
// First round of iteration to pick out `0.0.0.0/0` or `::/0` for the sake of excluding non-zero IPs.
|
||||
for _, cidr := range npa.cidrStrings {
|
||||
if IsZeroCIDR(cidr) {
|
||||
uniqueAddressList.Insert(cidr)
|
||||
}
|
||||
}
|
||||
|
||||
addrs, err := nw.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err)
|
||||
}
|
||||
|
||||
// Second round of iteration to parse IPs based on cidr.
|
||||
for _, cidr := range npa.cidrs {
|
||||
if IsZeroCIDR(cidr.String()) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
// nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux.
|
||||
switch v := addr.(type) {
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if cidr.Contains(ip) {
|
||||
if netutils.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) {
|
||||
uniqueAddressList.Insert(ip.String())
|
||||
}
|
||||
if !netutils.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) {
|
||||
uniqueAddressList.Insert(ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if uniqueAddressList.Len() == 0 {
|
||||
return nil, fmt.Errorf("no addresses found for cidrs %v", npa.cidrStrings)
|
||||
}
|
||||
|
||||
return uniqueAddressList, nil
|
||||
}
|
||||
|
||||
// ContainsIPv4Loopback returns true if npa's CIDRs contain an IPv4 loopback address.
|
||||
func (npa *NodePortAddresses) ContainsIPv4Loopback() bool {
|
||||
return npa.containsIPv4Loopback
|
||||
}
|
503
vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go
generated
vendored
503
vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go
generated
vendored
@ -1,503 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilrand "k8s.io/apimachinery/pkg/util/rand"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/tools/events"
|
||||
utilsysctl "k8s.io/component-helpers/node/util/sysctl"
|
||||
helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
netutils "k8s.io/utils/net"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
// IPv4ZeroCIDR is the CIDR block for the whole IPv4 address space
|
||||
IPv4ZeroCIDR = "0.0.0.0/0"
|
||||
|
||||
// IPv6ZeroCIDR is the CIDR block for the whole IPv6 address space
|
||||
IPv6ZeroCIDR = "::/0"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrAddressNotAllowed indicates the address is not allowed
|
||||
ErrAddressNotAllowed = errors.New("address not allowed")
|
||||
|
||||
// ErrNoAddresses indicates there are no addresses for the hostname
|
||||
ErrNoAddresses = errors.New("no addresses for hostname")
|
||||
)
|
||||
|
||||
// isValidEndpoint checks that the given host / port pair are valid endpoint
|
||||
func isValidEndpoint(host string, port int) bool {
|
||||
return host != "" && port > 0
|
||||
}
|
||||
|
||||
// BuildPortsToEndpointsMap builds a map of portname -> all ip:ports for that
|
||||
// portname. Explode Endpoints.Subsets[*] into this structure.
|
||||
func BuildPortsToEndpointsMap(endpoints *v1.Endpoints) map[string][]string {
|
||||
portsToEndpoints := map[string][]string{}
|
||||
for i := range endpoints.Subsets {
|
||||
ss := &endpoints.Subsets[i]
|
||||
for i := range ss.Ports {
|
||||
port := &ss.Ports[i]
|
||||
for i := range ss.Addresses {
|
||||
addr := &ss.Addresses[i]
|
||||
if isValidEndpoint(addr.IP, int(port.Port)) {
|
||||
portsToEndpoints[port.Name] = append(portsToEndpoints[port.Name], net.JoinHostPort(addr.IP, strconv.Itoa(int(port.Port))))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return portsToEndpoints
|
||||
}
|
||||
|
||||
// IsZeroCIDR checks whether the input CIDR string is either
|
||||
// the IPv4 or IPv6 zero CIDR
|
||||
func IsZeroCIDR(cidr string) bool {
|
||||
if cidr == IPv4ZeroCIDR || cidr == IPv6ZeroCIDR {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsLoopBack checks if a given IP address is a loopback address.
|
||||
func IsLoopBack(ip string) bool {
|
||||
netIP := netutils.ParseIPSloppy(ip)
|
||||
if netIP != nil {
|
||||
return netIP.IsLoopback()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsProxyableIP checks if a given IP address is permitted to be proxied
|
||||
func IsProxyableIP(ip string) error {
|
||||
netIP := netutils.ParseIPSloppy(ip)
|
||||
if netIP == nil {
|
||||
return ErrAddressNotAllowed
|
||||
}
|
||||
return isProxyableIP(netIP)
|
||||
}
|
||||
|
||||
func isProxyableIP(ip net.IP) error {
|
||||
if !ip.IsGlobalUnicast() {
|
||||
return ErrAddressNotAllowed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resolver is an interface for net.Resolver
|
||||
type Resolver interface {
|
||||
LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)
|
||||
}
|
||||
|
||||
// IsProxyableHostname checks if the IP addresses for a given hostname are permitted to be proxied
|
||||
func IsProxyableHostname(ctx context.Context, resolv Resolver, hostname string) error {
|
||||
resp, err := resolv.LookupIPAddr(ctx, hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(resp) == 0 {
|
||||
return ErrNoAddresses
|
||||
}
|
||||
|
||||
for _, host := range resp {
|
||||
if err := isProxyableIP(host.IP); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsAllowedHost checks if the given IP host address is in a network in the denied list.
|
||||
func IsAllowedHost(host net.IP, denied []*net.IPNet) error {
|
||||
for _, ipNet := range denied {
|
||||
if ipNet.Contains(host) {
|
||||
return ErrAddressNotAllowed
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLocalAddrs returns a list of all network addresses on the local system
|
||||
func GetLocalAddrs() ([]net.IP, error) {
|
||||
var localAddrs []net.IP
|
||||
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
ip, _, err := netutils.ParseCIDRSloppy(addr.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
localAddrs = append(localAddrs, ip)
|
||||
}
|
||||
|
||||
return localAddrs, nil
|
||||
}
|
||||
|
||||
// GetLocalAddrSet return a local IPSet.
|
||||
// If failed to get local addr, will assume no local ips.
|
||||
func GetLocalAddrSet() netutils.IPSet {
|
||||
localAddrs, err := GetLocalAddrs()
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to get local addresses assuming no local IPs")
|
||||
} else if len(localAddrs) == 0 {
|
||||
klog.InfoS("No local addresses were found")
|
||||
}
|
||||
|
||||
localAddrSet := netutils.IPSet{}
|
||||
localAddrSet.Insert(localAddrs...)
|
||||
return localAddrSet
|
||||
}
|
||||
|
||||
// ShouldSkipService checks if a given service should skip proxying
|
||||
func ShouldSkipService(service *v1.Service) bool {
|
||||
// if ClusterIP is "None" or empty, skip proxying
|
||||
if !helper.IsServiceIPSet(service) {
|
||||
klog.V(3).InfoS("Skipping service due to cluster IP", "service", klog.KObj(service), "clusterIP", service.Spec.ClusterIP)
|
||||
return true
|
||||
}
|
||||
// Even if ClusterIP is set, ServiceTypeExternalName services don't get proxied
|
||||
if service.Spec.Type == v1.ServiceTypeExternalName {
|
||||
klog.V(3).InfoS("Skipping service due to Type=ExternalName", "service", klog.KObj(service))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddressSet validates the addresses in the slice using the "isValid" function.
|
||||
// Addresses that pass the validation are returned as a string Set.
|
||||
func AddressSet(isValid func(ip net.IP) bool, addrs []net.Addr) sets.Set[string] {
|
||||
ips := sets.New[string]()
|
||||
for _, a := range addrs {
|
||||
var ip net.IP
|
||||
switch v := a.(type) {
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
if isValid(ip) {
|
||||
ips.Insert(ip.String())
|
||||
}
|
||||
}
|
||||
return ips
|
||||
}
|
||||
|
||||
// LogAndEmitIncorrectIPVersionEvent logs and emits incorrect IP version event.
|
||||
func LogAndEmitIncorrectIPVersionEvent(recorder events.EventRecorder, fieldName, fieldValue, svcNamespace, svcName string, svcUID types.UID) {
|
||||
errMsg := fmt.Sprintf("%s in %s has incorrect IP version", fieldValue, fieldName)
|
||||
klog.ErrorS(nil, "Incorrect IP version", "service", klog.KRef(svcNamespace, svcName), "field", fieldName, "value", fieldValue)
|
||||
if recorder != nil {
|
||||
recorder.Eventf(
|
||||
&v1.ObjectReference{
|
||||
Kind: "Service",
|
||||
Name: svcName,
|
||||
Namespace: svcNamespace,
|
||||
UID: svcUID,
|
||||
}, nil, v1.EventTypeWarning, "KubeProxyIncorrectIPVersion", "GatherEndpoints", errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
// MapIPsByIPFamily maps a slice of IPs to their respective IP families (v4 or v6)
|
||||
func MapIPsByIPFamily(ipStrings []string) map[v1.IPFamily][]string {
|
||||
ipFamilyMap := map[v1.IPFamily][]string{}
|
||||
for _, ip := range ipStrings {
|
||||
// Handle only the valid IPs
|
||||
if ipFamily, err := getIPFamilyFromIP(ip); err == nil {
|
||||
ipFamilyMap[ipFamily] = append(ipFamilyMap[ipFamily], ip)
|
||||
} else {
|
||||
// this function is called in multiple places. All of which
|
||||
// have sanitized data. Except the case of ExternalIPs which is
|
||||
// not validated by api-server. Specifically empty strings
|
||||
// validation. Which yields into a lot of bad error logs.
|
||||
// check for empty string
|
||||
if len(strings.TrimSpace(ip)) != 0 {
|
||||
klog.ErrorS(nil, "Skipping invalid IP", "ip", ip)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return ipFamilyMap
|
||||
}
|
||||
|
||||
// MapCIDRsByIPFamily maps a slice of IPs to their respective IP families (v4 or v6)
|
||||
func MapCIDRsByIPFamily(cidrStrings []string) map[v1.IPFamily][]string {
|
||||
ipFamilyMap := map[v1.IPFamily][]string{}
|
||||
for _, cidr := range cidrStrings {
|
||||
// Handle only the valid CIDRs
|
||||
if ipFamily, err := getIPFamilyFromCIDR(cidr); err == nil {
|
||||
ipFamilyMap[ipFamily] = append(ipFamilyMap[ipFamily], cidr)
|
||||
} else {
|
||||
klog.ErrorS(nil, "Skipping invalid CIDR", "cidr", cidr)
|
||||
}
|
||||
}
|
||||
return ipFamilyMap
|
||||
}
|
||||
|
||||
func getIPFamilyFromIP(ipStr string) (v1.IPFamily, error) {
|
||||
netIP := netutils.ParseIPSloppy(ipStr)
|
||||
if netIP == nil {
|
||||
return "", ErrAddressNotAllowed
|
||||
}
|
||||
|
||||
if netutils.IsIPv6(netIP) {
|
||||
return v1.IPv6Protocol, nil
|
||||
}
|
||||
return v1.IPv4Protocol, nil
|
||||
}
|
||||
|
||||
func getIPFamilyFromCIDR(cidrStr string) (v1.IPFamily, error) {
|
||||
_, netCIDR, err := netutils.ParseCIDRSloppy(cidrStr)
|
||||
if err != nil {
|
||||
return "", ErrAddressNotAllowed
|
||||
}
|
||||
if netutils.IsIPv6CIDR(netCIDR) {
|
||||
return v1.IPv6Protocol, nil
|
||||
}
|
||||
return v1.IPv4Protocol, nil
|
||||
}
|
||||
|
||||
// OtherIPFamily returns the other ip family
|
||||
func OtherIPFamily(ipFamily v1.IPFamily) v1.IPFamily {
|
||||
if ipFamily == v1.IPv6Protocol {
|
||||
return v1.IPv4Protocol
|
||||
}
|
||||
|
||||
return v1.IPv6Protocol
|
||||
}
|
||||
|
||||
// AppendPortIfNeeded appends the given port to IP address unless it is already in
|
||||
// "ipv4:port" or "[ipv6]:port" format.
|
||||
func AppendPortIfNeeded(addr string, port int32) string {
|
||||
// Return if address is already in "ipv4:port" or "[ipv6]:port" format.
|
||||
if _, _, err := net.SplitHostPort(addr); err == nil {
|
||||
return addr
|
||||
}
|
||||
|
||||
// Simply return for invalid case. This should be caught by validation instead.
|
||||
ip := netutils.ParseIPSloppy(addr)
|
||||
if ip == nil {
|
||||
return addr
|
||||
}
|
||||
|
||||
// Append port to address.
|
||||
if ip.To4() != nil {
|
||||
return fmt.Sprintf("%s:%d", addr, port)
|
||||
}
|
||||
return fmt.Sprintf("[%s]:%d", addr, port)
|
||||
}
|
||||
|
||||
// ShuffleStrings copies strings from the specified slice into a copy in random
|
||||
// order. It returns a new slice.
|
||||
func ShuffleStrings(s []string) []string {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
shuffled := make([]string, len(s))
|
||||
perm := utilrand.Perm(len(s))
|
||||
for i, j := range perm {
|
||||
shuffled[j] = s[i]
|
||||
}
|
||||
return shuffled
|
||||
}
|
||||
|
||||
// EnsureSysctl sets a kernel sysctl to a given numeric value.
|
||||
func EnsureSysctl(sysctl utilsysctl.Interface, name string, newVal int) error {
|
||||
if oldVal, _ := sysctl.GetSysctl(name); oldVal != newVal {
|
||||
if err := sysctl.SetSysctl(name, newVal); err != nil {
|
||||
return fmt.Errorf("can't set sysctl %s to %d: %v", name, newVal, err)
|
||||
}
|
||||
klog.V(1).InfoS("Changed sysctl", "name", name, "before", oldVal, "after", newVal)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DialContext is a dial function matching the signature of net.Dialer.DialContext.
|
||||
type DialContext = func(context.Context, string, string) (net.Conn, error)
|
||||
|
||||
// FilteredDialOptions configures how a DialContext is wrapped by NewFilteredDialContext.
|
||||
type FilteredDialOptions struct {
|
||||
// DialHostIPDenylist restricts hosts from being dialed.
|
||||
DialHostCIDRDenylist []*net.IPNet
|
||||
// AllowLocalLoopback controls connections to local loopback hosts (as defined by
|
||||
// IsProxyableIP).
|
||||
AllowLocalLoopback bool
|
||||
}
|
||||
|
||||
// NewFilteredDialContext returns a DialContext function that filters connections based on a FilteredDialOptions.
|
||||
func NewFilteredDialContext(wrapped DialContext, resolv Resolver, opts *FilteredDialOptions) DialContext {
|
||||
if wrapped == nil {
|
||||
wrapped = http.DefaultTransport.(*http.Transport).DialContext
|
||||
}
|
||||
if opts == nil {
|
||||
// Do no filtering
|
||||
return wrapped
|
||||
}
|
||||
if resolv == nil {
|
||||
resolv = net.DefaultResolver
|
||||
}
|
||||
if len(opts.DialHostCIDRDenylist) == 0 && opts.AllowLocalLoopback {
|
||||
// Do no filtering.
|
||||
return wrapped
|
||||
}
|
||||
return func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
// DialContext is given host:port. LookupIPAddress expects host.
|
||||
addressToResolve, _, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
addressToResolve = address
|
||||
}
|
||||
|
||||
resp, err := resolv.LookupIPAddr(ctx, addressToResolve)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(resp) == 0 {
|
||||
return nil, ErrNoAddresses
|
||||
}
|
||||
|
||||
for _, host := range resp {
|
||||
if !opts.AllowLocalLoopback {
|
||||
if err := isProxyableIP(host.IP); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if opts.DialHostCIDRDenylist != nil {
|
||||
if err := IsAllowedHost(host.IP, opts.DialHostCIDRDenylist); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return wrapped(ctx, network, address)
|
||||
}
|
||||
}
|
||||
|
||||
// GetClusterIPByFamily returns a service clusterip by family
|
||||
func GetClusterIPByFamily(ipFamily v1.IPFamily, service *v1.Service) string {
|
||||
// allowing skew
|
||||
if len(service.Spec.IPFamilies) == 0 {
|
||||
if len(service.Spec.ClusterIP) == 0 || service.Spec.ClusterIP == v1.ClusterIPNone {
|
||||
return ""
|
||||
}
|
||||
|
||||
IsIPv6Family := (ipFamily == v1.IPv6Protocol)
|
||||
if IsIPv6Family == netutils.IsIPv6String(service.Spec.ClusterIP) {
|
||||
return service.Spec.ClusterIP
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
for idx, family := range service.Spec.IPFamilies {
|
||||
if family == ipFamily {
|
||||
if idx < len(service.Spec.ClusterIPs) {
|
||||
return service.Spec.ClusterIPs[idx]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
type LineBuffer struct {
|
||||
b bytes.Buffer
|
||||
lines int
|
||||
}
|
||||
|
||||
// Write takes a list of arguments, each a string or []string, joins all the
|
||||
// individual strings with spaces, terminates with newline, and writes to buf.
|
||||
// Any other argument type will panic.
|
||||
func (buf *LineBuffer) Write(args ...interface{}) {
|
||||
for i, arg := range args {
|
||||
if i > 0 {
|
||||
buf.b.WriteByte(' ')
|
||||
}
|
||||
switch x := arg.(type) {
|
||||
case string:
|
||||
buf.b.WriteString(x)
|
||||
case []string:
|
||||
for j, s := range x {
|
||||
if j > 0 {
|
||||
buf.b.WriteByte(' ')
|
||||
}
|
||||
buf.b.WriteString(s)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown argument type: %T", x))
|
||||
}
|
||||
}
|
||||
buf.b.WriteByte('\n')
|
||||
buf.lines++
|
||||
}
|
||||
|
||||
// WriteBytes writes bytes to buffer, and terminates with newline.
|
||||
func (buf *LineBuffer) WriteBytes(bytes []byte) {
|
||||
buf.b.Write(bytes)
|
||||
buf.b.WriteByte('\n')
|
||||
buf.lines++
|
||||
}
|
||||
|
||||
// Reset clears buf
|
||||
func (buf *LineBuffer) Reset() {
|
||||
buf.b.Reset()
|
||||
buf.lines = 0
|
||||
}
|
||||
|
||||
// Bytes returns the contents of buf as a []byte
|
||||
func (buf *LineBuffer) Bytes() []byte {
|
||||
return buf.b.Bytes()
|
||||
}
|
||||
|
||||
// Lines returns the number of lines in buf. Note that more precisely, this returns the
|
||||
// number of times Write() or WriteBytes() was called; it assumes that you never wrote
|
||||
// any newlines to the buffer yourself.
|
||||
func (buf *LineBuffer) Lines() int {
|
||||
return buf.lines
|
||||
}
|
||||
|
||||
// RevertPorts is closing ports in replacementPortsMap but not in originalPortsMap. In other words, it only
|
||||
// closes the ports opened in this sync.
|
||||
func RevertPorts(replacementPortsMap, originalPortsMap map[netutils.LocalPort]netutils.Closeable) {
|
||||
for k, v := range replacementPortsMap {
|
||||
// Only close newly opened local ports - leave ones that were open before this update
|
||||
if originalPortsMap[k] == nil {
|
||||
klog.V(2).InfoS("Closing local port", "port", k.String())
|
||||
v.Close()
|
||||
}
|
||||
}
|
||||
}
|
11
vendor/k8s.io/kubernetes/pkg/util/hash/hash.go
generated
vendored
11
vendor/k8s.io/kubernetes/pkg/util/hash/hash.go
generated
vendored
@ -17,9 +17,10 @@ limitations under the License.
|
||||
package hash
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"k8s.io/apimachinery/pkg/util/dump"
|
||||
)
|
||||
|
||||
// DeepHashObject writes specified object to hash using the spew library
|
||||
@ -27,11 +28,5 @@ import (
|
||||
// ensuring the hash does not change when a pointer changes.
|
||||
func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) {
|
||||
hasher.Reset()
|
||||
printer := spew.ConfigState{
|
||||
Indent: " ",
|
||||
SortKeys: true,
|
||||
DisableMethods: true,
|
||||
SpewKeys: true,
|
||||
}
|
||||
printer.Fprintf(hasher, "%#v", objectToWrite)
|
||||
fmt.Fprintf(hasher, "%v", dump.ForHash(objectToWrite))
|
||||
}
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/util/parsers/parsers.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/util/parsers/parsers.go
generated
vendored
@ -31,7 +31,7 @@ import (
|
||||
func ParseImageName(image string) (string, string, string, error) {
|
||||
named, err := dockerref.ParseNormalizedNamed(image)
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("couldn't parse image name: %v", err)
|
||||
return "", "", "", fmt.Errorf("couldn't parse image name %q: %v", image, err)
|
||||
}
|
||||
|
||||
repoToPull := named.Name()
|
||||
|
75
vendor/k8s.io/kubernetes/pkg/util/slice/slice.go
generated
vendored
75
vendor/k8s.io/kubernetes/pkg/util/slice/slice.go
generated
vendored
@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package slice provides utility methods for common operations on slices.
|
||||
package slice
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// CopyStrings copies the contents of the specified string slice
|
||||
// into a new slice.
|
||||
func CopyStrings(s []string) []string {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
c := make([]string, len(s))
|
||||
copy(c, s)
|
||||
return c
|
||||
}
|
||||
|
||||
// SortStrings sorts the specified string slice in place. It returns the same
|
||||
// slice that was provided in order to facilitate method chaining.
|
||||
func SortStrings(s []string) []string {
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// ContainsString checks if a given slice of strings contains the provided string.
|
||||
// If a modifier func is provided, it is called with the slice item before the comparation.
|
||||
func ContainsString(slice []string, s string, modifier func(s string) string) bool {
|
||||
for _, item := range slice {
|
||||
if item == s {
|
||||
return true
|
||||
}
|
||||
if modifier != nil && modifier(item) == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveString returns a newly created []string that contains all items from slice that
|
||||
// are not equal to s and modifier(s) in case modifier func is provided.
|
||||
func RemoveString(slice []string, s string, modifier func(s string) string) []string {
|
||||
newSlice := make([]string, 0)
|
||||
for _, item := range slice {
|
||||
if item == s {
|
||||
continue
|
||||
}
|
||||
if modifier != nil && modifier(item) == s {
|
||||
continue
|
||||
}
|
||||
newSlice = append(newSlice, item)
|
||||
}
|
||||
if len(newSlice) == 0 {
|
||||
// Sanitize for unit tests so we don't need to distinguish empty array
|
||||
// and nil.
|
||||
newSlice = nil
|
||||
}
|
||||
return newSlice
|
||||
}
|
10
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
@ -40,7 +40,6 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
|
||||
"k8s.io/kubernetes/pkg/volume/util/hostutil"
|
||||
"k8s.io/kubernetes/pkg/volume/util/recyclerclient"
|
||||
"k8s.io/kubernetes/pkg/volume/util/subpath"
|
||||
@ -443,9 +442,6 @@ type VolumeHost interface {
|
||||
|
||||
// Returns an interface that should be used to execute subpath operations
|
||||
GetSubpather() subpath.Interface
|
||||
|
||||
// Returns options to pass for proxyutil filtered dialers.
|
||||
GetFilteredDialOptions() *proxyutil.FilteredDialOptions
|
||||
}
|
||||
|
||||
// VolumePluginMgr tracks registered plugins.
|
||||
@ -694,13 +690,11 @@ func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
|
||||
return match, nil
|
||||
}
|
||||
|
||||
// FindPluginByName fetches a plugin by name or by legacy name. If no plugin
|
||||
// is found, returns error.
|
||||
// FindPluginByName fetches a plugin by name. If no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindPluginByName(name string) (VolumePlugin, error) {
|
||||
pm.mutex.RLock()
|
||||
defer pm.mutex.RUnlock()
|
||||
|
||||
// Once we can get rid of legacy names we can reduce this to a map lookup.
|
||||
var match VolumePlugin
|
||||
if v, found := pm.plugins[name]; found {
|
||||
match = v
|
||||
@ -1065,7 +1059,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
|
||||
Name: "pv-recycler",
|
||||
Image: "registry.k8s.io/debian-base:v2.0.0",
|
||||
Command: []string{"/bin/sh"},
|
||||
Args: []string{"-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"},
|
||||
Args: []string{"-c", "test -e /scrub && find /scrub -mindepth 1 -delete && test -z \"$(ls -A /scrub)\" || exit 1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: "vol",
|
||||
|
9
vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go
generated
vendored
@ -19,7 +19,6 @@ package util
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@ -327,7 +326,7 @@ func shouldWriteFile(path string, content []byte) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
contentOnFs, err := ioutil.ReadFile(path)
|
||||
contentOnFs, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -379,7 +378,7 @@ func (w *AtomicWriter) pathsToRemove(payload map[string]FileProjection, oldTsDir
|
||||
|
||||
// newTimestampDir creates a new timestamp directory
|
||||
func (w *AtomicWriter) newTimestampDir() (string, error) {
|
||||
tsDir, err := ioutil.TempDir(w.targetDir, time.Now().UTC().Format("..2006_01_02_15_04_05."))
|
||||
tsDir, err := os.MkdirTemp(w.targetDir, time.Now().UTC().Format("..2006_01_02_15_04_05."))
|
||||
if err != nil {
|
||||
klog.Errorf("%s: unable to create new temp directory: %v", w.logContext, err)
|
||||
return "", err
|
||||
@ -411,11 +410,11 @@ func (w *AtomicWriter) writePayloadToDir(payload map[string]FileProjection, dir
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(fullPath, content, mode); err != nil {
|
||||
if err := os.WriteFile(fullPath, content, mode); err != nil {
|
||||
klog.Errorf("%s: unable to write file %s with mode %v: %v", w.logContext, fullPath, mode, err)
|
||||
return err
|
||||
}
|
||||
// Chmod is needed because ioutil.WriteFile() ends up calling
|
||||
// Chmod is needed because os.WriteFile() ends up calling
|
||||
// open(2) to create the file, so the final mode used is "mode &
|
||||
// ~umask". But we want to make sure the specified mode is used
|
||||
// in the file no matter what the umask is.
|
||||
|
3
vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go
generated
vendored
@ -22,7 +22,6 @@ package common
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
@ -144,7 +143,7 @@ func doRunXFSQuotaCommand(mountpoint string, mountsFile, command string) (string
|
||||
// See https://bugzilla.redhat.com/show_bug.cgi?id=237120 for an example
|
||||
// of the problem that could be caused if this were to happen.
|
||||
func runXFSQuotaCommand(mountpoint string, command string) (string, error) {
|
||||
tmpMounts, err := ioutil.TempFile("", "mounts")
|
||||
tmpMounts, err := os.CreateTemp("", "mounts")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot create temporary mount file: %v", err)
|
||||
}
|
||||
|
3
vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go
generated
vendored
@ -22,7 +22,6 @@ package fsquota
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@ -267,7 +266,7 @@ func writeProjectFile(base *os.File, projects []projectType) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
mode := stat.Mode() & os.ModePerm
|
||||
f, err := ioutil.TempFile(filepath.Dir(oname), filepath.Base(oname))
|
||||
f, err := os.CreateTemp(filepath.Dir(oname), filepath.Base(oname))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
9
vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go
generated
vendored
@ -353,10 +353,11 @@ func AssignQuota(m mount.Interface, path string, poduid types.UID, bytes *resour
|
||||
}
|
||||
// When enforcing quotas are enabled, we'll condition this
|
||||
// on their being disabled also.
|
||||
if ibytes > 0 {
|
||||
ibytes = -1
|
||||
fsbytes := ibytes
|
||||
if fsbytes > 0 {
|
||||
fsbytes = -1
|
||||
}
|
||||
if err = setQuotaOnDir(path, id, ibytes); err == nil {
|
||||
if err = setQuotaOnDir(path, id, fsbytes); err == nil {
|
||||
quotaPodMap[id] = internalPodUid
|
||||
quotaSizeMap[id] = ibytes
|
||||
podQuotaMap[internalPodUid] = id
|
||||
@ -364,7 +365,7 @@ func AssignQuota(m mount.Interface, path string, poduid types.UID, bytes *resour
|
||||
dirPodMap[path] = internalPodUid
|
||||
podUidMap[internalPodUid] = externalPodUid
|
||||
podDirCountMap[internalPodUid]++
|
||||
klog.V(4).Infof("Assigning quota ID %d (%d) to %s", id, ibytes, path)
|
||||
klog.V(4).Infof("Assigning quota ID %d (request limit %d, actual limit %d) to %s", id, ibytes, fsbytes, path)
|
||||
return nil
|
||||
}
|
||||
removeProjectID(path, id)
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/volume/util/io_util.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/util/io_util.go
generated
vendored
@ -38,7 +38,7 @@ func NewIOHandler() IoUtil {
|
||||
}
|
||||
|
||||
func (handler *osIOHandler) ReadFile(filename string) ([]byte, error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
return os.ReadFile(filename)
|
||||
}
|
||||
func (handler *osIOHandler) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(dirname)
|
||||
|
52
vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go
generated
vendored
52
vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go
generated
vendored
@ -152,12 +152,11 @@ func MarkControllerReisizeInProgress(pvc *v1.PersistentVolumeClaim, resizerName
|
||||
Status: v1.ConditionTrue,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
}
|
||||
controllerExpansionInProgress := v1.PersistentVolumeClaimControllerExpansionInProgress
|
||||
conditions := []v1.PersistentVolumeClaimCondition{progressCondition}
|
||||
newPVC := pvc.DeepCopy()
|
||||
newPVC = MergeResizeConditionOnPVC(newPVC, conditions)
|
||||
newPVC.Status.ResizeStatus = &controllerExpansionInProgress
|
||||
newPVC.Status.AllocatedResources = v1.ResourceList{v1.ResourceStorage: newSize}
|
||||
newPVC = mergeStorageResourceStatus(newPVC, v1.PersistentVolumeClaimControllerResizeInProgress)
|
||||
newPVC = mergeStorageAllocatedResources(newPVC, newSize)
|
||||
newPVC = setResizer(newPVC, resizerName)
|
||||
return PatchPVCStatus(pvc /*oldPVC*/, newPVC, kubeClient)
|
||||
}
|
||||
@ -192,10 +191,11 @@ func MarkForFSResize(
|
||||
}
|
||||
conditions := []v1.PersistentVolumeClaimCondition{pvcCondition}
|
||||
newPVC := pvc.DeepCopy()
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure) {
|
||||
expansionPendingOnNode := v1.PersistentVolumeClaimNodeExpansionPending
|
||||
newPVC.Status.ResizeStatus = &expansionPendingOnNode
|
||||
newPVC = mergeStorageResourceStatus(newPVC, v1.PersistentVolumeClaimNodeResizePending)
|
||||
}
|
||||
|
||||
newPVC = MergeResizeConditionOnPVC(newPVC, conditions)
|
||||
updatedPVC, err := PatchPVCStatus(pvc /*oldPVC*/, newPVC, kubeClient)
|
||||
return updatedPVC, err
|
||||
@ -220,8 +220,13 @@ func MarkFSResizeFinished(
|
||||
|
||||
// if RecoverVolumeExpansionFailure is enabled, we need to reset ResizeStatus back to nil
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure) {
|
||||
expansionFinished := v1.PersistentVolumeClaimNoExpansionInProgress
|
||||
newPVC.Status.ResizeStatus = &expansionFinished
|
||||
allocatedResourceStatusMap := newPVC.Status.AllocatedResourceStatuses
|
||||
delete(allocatedResourceStatusMap, v1.ResourceStorage)
|
||||
if len(allocatedResourceStatusMap) == 0 {
|
||||
newPVC.Status.AllocatedResourceStatuses = nil
|
||||
} else {
|
||||
newPVC.Status.AllocatedResourceStatuses = allocatedResourceStatusMap
|
||||
}
|
||||
}
|
||||
|
||||
newPVC = MergeResizeConditionOnPVC(newPVC, []v1.PersistentVolumeClaimCondition{})
|
||||
@ -232,9 +237,9 @@ func MarkFSResizeFinished(
|
||||
// MarkNodeExpansionFailed marks a PVC for node expansion as failed. Kubelet should not retry expansion
|
||||
// of volumes which are in failed state.
|
||||
func MarkNodeExpansionFailed(pvc *v1.PersistentVolumeClaim, kubeClient clientset.Interface) (*v1.PersistentVolumeClaim, error) {
|
||||
expansionFailedOnNode := v1.PersistentVolumeClaimNodeExpansionFailed
|
||||
newPVC := pvc.DeepCopy()
|
||||
newPVC.Status.ResizeStatus = &expansionFailedOnNode
|
||||
newPVC = mergeStorageResourceStatus(newPVC, v1.PersistentVolumeClaimNodeResizeFailed)
|
||||
|
||||
patchBytes, err := createPVCPatch(pvc, newPVC, false /* addResourceVersionCheck */)
|
||||
if err != nil {
|
||||
return pvc, fmt.Errorf("patchPVCStatus failed to patch PVC %q: %v", pvc.Name, err)
|
||||
@ -250,9 +255,8 @@ func MarkNodeExpansionFailed(pvc *v1.PersistentVolumeClaim, kubeClient clientset
|
||||
|
||||
// MarkNodeExpansionInProgress marks pvc expansion in progress on node
|
||||
func MarkNodeExpansionInProgress(pvc *v1.PersistentVolumeClaim, kubeClient clientset.Interface) (*v1.PersistentVolumeClaim, error) {
|
||||
nodeExpansionInProgress := v1.PersistentVolumeClaimNodeExpansionInProgress
|
||||
newPVC := pvc.DeepCopy()
|
||||
newPVC.Status.ResizeStatus = &nodeExpansionInProgress
|
||||
newPVC = mergeStorageResourceStatus(newPVC, v1.PersistentVolumeClaimNodeResizeInProgress)
|
||||
updatedPVC, err := PatchPVCStatus(pvc /* oldPVC */, newPVC, kubeClient)
|
||||
return updatedPVC, err
|
||||
}
|
||||
@ -365,6 +369,32 @@ func MergeResizeConditionOnPVC(
|
||||
return pvc
|
||||
}
|
||||
|
||||
func mergeStorageResourceStatus(pvc *v1.PersistentVolumeClaim, status v1.ClaimResourceStatus) *v1.PersistentVolumeClaim {
|
||||
allocatedResourceStatusMap := pvc.Status.AllocatedResourceStatuses
|
||||
if allocatedResourceStatusMap == nil {
|
||||
pvc.Status.AllocatedResourceStatuses = map[v1.ResourceName]v1.ClaimResourceStatus{
|
||||
v1.ResourceStorage: status,
|
||||
}
|
||||
return pvc
|
||||
}
|
||||
allocatedResourceStatusMap[v1.ResourceStorage] = status
|
||||
pvc.Status.AllocatedResourceStatuses = allocatedResourceStatusMap
|
||||
return pvc
|
||||
}
|
||||
|
||||
func mergeStorageAllocatedResources(pvc *v1.PersistentVolumeClaim, size resource.Quantity) *v1.PersistentVolumeClaim {
|
||||
allocatedResourcesMap := pvc.Status.AllocatedResources
|
||||
if allocatedResourcesMap == nil {
|
||||
pvc.Status.AllocatedResources = map[v1.ResourceName]resource.Quantity{
|
||||
v1.ResourceStorage: size,
|
||||
}
|
||||
return pvc
|
||||
}
|
||||
allocatedResourcesMap[v1.ResourceStorage] = size
|
||||
pvc.Status.AllocatedResources = allocatedResourcesMap
|
||||
return pvc
|
||||
}
|
||||
|
||||
// GenericResizeFS : call generic filesystem resizer for plugins that don't have any special filesystem resize requirements
|
||||
func GenericResizeFS(host volume.VolumeHost, pluginName, devicePath, deviceMountPath string) (bool, error) {
|
||||
resizer := mount.NewResizeFs(host.GetExec(pluginName))
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/volume/util/storageclass.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/util/storageclass.go
generated
vendored
@ -64,7 +64,7 @@ func GetDefaultClass(lister storagev1listers.StorageClassLister) (*storagev1.Sto
|
||||
return defaultClasses[i].CreationTimestamp.UnixNano() > defaultClasses[j].CreationTimestamp.UnixNano()
|
||||
})
|
||||
if len(defaultClasses) > 1 {
|
||||
klog.V(4).Infof("%d default StorageClasses were found, choosing the newest: %s", len(defaultClasses), defaultClasses[0].Name)
|
||||
klog.V(4).Infof("%d default StorageClasses were found, choosing: %s", len(defaultClasses), defaultClasses[0].Name)
|
||||
}
|
||||
|
||||
return defaultClasses[0], nil
|
||||
|
9
vendor/k8s.io/kubernetes/pkg/volume/util/util.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/volume/util/util.go
generated
vendored
@ -19,7 +19,6 @@ package util
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@ -173,7 +172,7 @@ func LoadPodFromFile(filePath string) (*v1.Pod, error) {
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("file path not specified")
|
||||
}
|
||||
podDef, err := ioutil.ReadFile(filePath)
|
||||
podDef, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err)
|
||||
}
|
||||
@ -688,9 +687,9 @@ func HasMountRefs(mountPath string, mountRefs []string) bool {
|
||||
// Neither of the above should be counted as a mount ref as those are handled
|
||||
// by the kubelet. What we're concerned about is a path like
|
||||
// /data/local/some/manual/mount
|
||||
// As unmonting could interrupt usage from that mountpoint.
|
||||
// As unmounting could interrupt usage from that mountpoint.
|
||||
//
|
||||
// So instead of looking for the entire /var/lib/... path, the plugins/kuberentes.io/
|
||||
// So instead of looking for the entire /var/lib/... path, the plugins/kubernetes.io/
|
||||
// suffix is trimmed off and searched for.
|
||||
//
|
||||
// If there isn't a /plugins/... path, the whole mountPath is used instead.
|
||||
@ -706,7 +705,7 @@ func HasMountRefs(mountPath string, mountRefs []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// WriteVolumeCache flush disk data given the spcified mount path
|
||||
// WriteVolumeCache flush disk data given the specified mount path
|
||||
func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error {
|
||||
// If runtime os is windows, execute Write-VolumeCache powershell command on the disk
|
||||
if runtime.GOOS == "windows" {
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler.go
generated
vendored
@ -18,7 +18,6 @@ package volumepathhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@ -279,12 +278,12 @@ func (v VolumePathHandler) IsDeviceBindMountExist(mapPath string) (bool, error)
|
||||
// GetDeviceBindMountRefs searches bind mounts under global map path
|
||||
func (v VolumePathHandler) GetDeviceBindMountRefs(devPath string, mapPath string) ([]string, error) {
|
||||
var refs []string
|
||||
files, err := ioutil.ReadDir(mapPath)
|
||||
files, err := os.ReadDir(mapPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.Mode()&os.ModeDevice != os.ModeDevice {
|
||||
if file.Type()&os.ModeDevice != os.ModeDevice {
|
||||
continue
|
||||
}
|
||||
filename := file.Name()
|
||||
|
@ -22,7 +22,6 @@ package volumepathhandler
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@ -133,7 +132,7 @@ func getLoopDeviceFromSysfs(path string) (string, error) {
|
||||
backingFile := fmt.Sprintf("%s/loop/backing_file", device)
|
||||
|
||||
// The contents of this file is the absolute path of "path".
|
||||
data, err := ioutil.ReadFile(backingFile)
|
||||
data, err := os.ReadFile(backingFile)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
9
vendor/k8s.io/kubernetes/test/e2e/framework/.import-restrictions
generated
vendored
9
vendor/k8s.io/kubernetes/test/e2e/framework/.import-restrictions
generated
vendored
@ -1,13 +1,6 @@
|
||||
rules:
|
||||
# The core E2E framework is meant to be a normal Kubernetes client,
|
||||
# which means that it shouldn't depend on internal
|
||||
# code. But we are not there yet, so some exceptions
|
||||
# have to be allowed. Over time the list of allowed
|
||||
# packages should get shorter, not longer.
|
||||
- selectorRegexp: ^k8s[.]io/kubernetes/pkg/
|
||||
allowedPrefixes:
|
||||
- k8s.io/kubernetes/pkg/kubelet/apis/
|
||||
|
||||
# which means that it shouldn't depend on internal code.
|
||||
# The following packages are okay to use:
|
||||
#
|
||||
# public API
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/config/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/config/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/debug/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/debug/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
6
vendor/k8s.io/kubernetes/test/e2e/framework/expect.go
generated
vendored
6
vendor/k8s.io/kubernetes/test/e2e/framework/expect.go
generated
vendored
@ -81,7 +81,7 @@ var _ types.GomegaMatcher = &matcher[string]{}
|
||||
// assertions. The difference is that failed assertions are returned as an
|
||||
// error:
|
||||
//
|
||||
// if err := Gomega().Expect(pod.Status.Phase).To(gomega.BeEqual(v1.Running)); err != nil {
|
||||
// if err := Gomega().Expect(pod.Status.Phase).To(gomega.Equal(v1.Running)); err != nil {
|
||||
// return fmt.Errorf("test pod not running: %w", err)
|
||||
// }
|
||||
//
|
||||
@ -294,14 +294,14 @@ var ErrFailure error = FailureError{}
|
||||
|
||||
// ExpectEqual expects the specified two are the same, otherwise an exception raises
|
||||
//
|
||||
// Deprecated: use gomega.Expect().To(gomega.BeEqual())
|
||||
// Deprecated: use gomega.Expect().To(gomega.Equal())
|
||||
func ExpectEqual(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.Equal(extra), explain...)
|
||||
}
|
||||
|
||||
// ExpectNotEqual expects the specified two are not the same, otherwise an exception raises
|
||||
//
|
||||
// Deprecated: use gomega.Expect().ToNot(gomega.BeEqual())
|
||||
// Deprecated: use gomega.Expect().ToNot(gomega.Equal())
|
||||
func ExpectNotEqual(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
gomega.ExpectWithOffset(1, actual).NotTo(gomega.Equal(extra), explain...)
|
||||
}
|
||||
|
26
vendor/k8s.io/kubernetes/test/e2e/framework/framework.go
generated
vendored
26
vendor/k8s.io/kubernetes/test/e2e/framework/framework.go
generated
vendored
@ -89,6 +89,12 @@ var (
|
||||
|
||||
// Framework supports common operations used by e2e tests; it will keep a client & a namespace for you.
|
||||
// Eventual goal is to merge this with integration test framework.
|
||||
//
|
||||
// You can configure the pod security level for your test by setting the `NamespacePodSecurityLevel`
|
||||
// which will set all three of pod security admission enforce, warn and audit labels on the namespace.
|
||||
// The default pod security profile is "restricted".
|
||||
// Each of the labels can be overridden by using more specific NamespacePodSecurity* attributes of this
|
||||
// struct.
|
||||
type Framework struct {
|
||||
BaseName string
|
||||
|
||||
@ -111,6 +117,9 @@ type Framework struct {
|
||||
namespacesToDelete []*v1.Namespace // Some tests have more than one.
|
||||
NamespaceDeletionTimeout time.Duration
|
||||
NamespacePodSecurityEnforceLevel admissionapi.Level // The pod security enforcement level for namespaces to be applied.
|
||||
NamespacePodSecurityWarnLevel admissionapi.Level // The pod security warn (client logging) level for namespaces to be applied.
|
||||
NamespacePodSecurityAuditLevel admissionapi.Level // The pod security audit (server logging) level for namespaces to be applied.
|
||||
NamespacePodSecurityLevel admissionapi.Level // The pod security level to be used for all of enforcement, warn and audit. Can be rewritten by more specific configuration attributes.
|
||||
|
||||
// Flaky operation failures in an e2e test can be captured through this.
|
||||
flakeReport *FlakeReport
|
||||
@ -448,11 +457,9 @@ func (f *Framework) CreateNamespace(ctx context.Context, baseName string, labels
|
||||
labels = labelsCopy
|
||||
}
|
||||
|
||||
enforceLevel := admissionapi.LevelRestricted
|
||||
if f.NamespacePodSecurityEnforceLevel != "" {
|
||||
enforceLevel = f.NamespacePodSecurityEnforceLevel
|
||||
}
|
||||
labels[admissionapi.EnforceLevelLabel] = string(enforceLevel)
|
||||
labels[admissionapi.EnforceLevelLabel] = firstNonEmptyPSaLevelOrRestricted(f.NamespacePodSecurityEnforceLevel, f.NamespacePodSecurityLevel)
|
||||
labels[admissionapi.WarnLevelLabel] = firstNonEmptyPSaLevelOrRestricted(f.NamespacePodSecurityWarnLevel, f.NamespacePodSecurityLevel)
|
||||
labels[admissionapi.AuditLevelLabel] = firstNonEmptyPSaLevelOrRestricted(f.NamespacePodSecurityAuditLevel, f.NamespacePodSecurityLevel)
|
||||
|
||||
ns, err := createTestingNS(ctx, baseName, f.ClientSet, labels)
|
||||
// check ns instead of err to see if it's nil as we may
|
||||
@ -481,6 +488,15 @@ func (f *Framework) CreateNamespace(ctx context.Context, baseName string, labels
|
||||
return ns, err
|
||||
}
|
||||
|
||||
func firstNonEmptyPSaLevelOrRestricted(levelConfig ...admissionapi.Level) string {
|
||||
for _, l := range levelConfig {
|
||||
if len(l) > 0 {
|
||||
return string(l)
|
||||
}
|
||||
}
|
||||
return string(admissionapi.LevelRestricted)
|
||||
}
|
||||
|
||||
// createSecretFromDockerConfig creates a secret using the private image registry credentials.
|
||||
// The credentials are provided by --e2e-docker-config-file flag.
|
||||
func (f *Framework) createSecretFromDockerConfig(ctx context.Context, namespace string) (*v1.Secret, error) {
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
2
vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go
generated
vendored
@ -49,7 +49,7 @@ func NewKubectlCommand(namespace string, args ...string) *KubectlBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEnv appends the given environment and returns itself.
|
||||
// AppendEnv appends the given environment and returns itself.
|
||||
func (b *KubectlBuilder) AppendEnv(env []string) *KubectlBuilder {
|
||||
if b.cmd.Env == nil {
|
||||
b.cmd.Env = os.Environ()
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go
generated
vendored
@ -44,7 +44,7 @@ const (
|
||||
// Taken from k8s.io/kubernetes/pkg/kubelet/metrics
|
||||
podStartDurationKey = "pod_start_duration_seconds"
|
||||
// Taken from k8s.io/kubernetes/pkg/kubelet/metrics
|
||||
PodStartSLIDurationKey = "pod_start_sli_duration_seconds"
|
||||
podStartSLIDurationKey = "pod_start_sli_duration_seconds"
|
||||
// Taken from k8s.io/kubernetes/pkg/kubelet/metrics
|
||||
cgroupManagerOperationsKey = "cgroup_manager_duration_seconds"
|
||||
// Taken from k8s.io/kubernetes/pkg/kubelet/metrics
|
||||
@ -155,7 +155,7 @@ func GetDefaultKubeletLatencyMetrics(ms KubeletMetrics) KubeletLatencyMetrics {
|
||||
podWorkerDurationKey,
|
||||
podWorkerStartDurationKey,
|
||||
podStartDurationKey,
|
||||
PodStartSLIDurationKey,
|
||||
podStartSLIDurationKey,
|
||||
cgroupManagerOperationsKey,
|
||||
dockerOperationsLatencyKey,
|
||||
podWorkerStartDurationKey,
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/node/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/node/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go
generated
vendored
@ -536,7 +536,7 @@ func GetClusterZones(ctx context.Context, c clientset.Interface) (sets.String, e
|
||||
}
|
||||
|
||||
// GetSchedulableClusterZones returns the values of zone label collected from all nodes which are schedulable.
|
||||
func GetSchedulableClusterZones(ctx context.Context, c clientset.Interface) (sets.String, error) {
|
||||
func GetSchedulableClusterZones(ctx context.Context, c clientset.Interface) (sets.Set[string], error) {
|
||||
// GetReadySchedulableNodes already filters our tainted and unschedulable nodes.
|
||||
nodes, err := GetReadySchedulableNodes(ctx, c)
|
||||
if err != nil {
|
||||
@ -544,7 +544,7 @@ func GetSchedulableClusterZones(ctx context.Context, c clientset.Interface) (set
|
||||
}
|
||||
|
||||
// collect values of zone label from all nodes
|
||||
zones := sets.NewString()
|
||||
zones := sets.New[string]()
|
||||
for _, node := range nodes.Items {
|
||||
if zone, found := node.Labels[v1.LabelFailureDomainBetaZone]; found {
|
||||
zones.Insert(zone)
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/pod/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/pod/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
27
vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go
generated
vendored
27
vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||
admissionapi "k8s.io/pod-security-admission/api"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -40,7 +41,7 @@ type Config struct {
|
||||
PVCs []*v1.PersistentVolumeClaim
|
||||
PVCsReadOnly bool
|
||||
InlineVolumeSources []*v1.VolumeSource
|
||||
IsPrivileged bool
|
||||
SecurityLevel admissionapi.Level
|
||||
Command string
|
||||
HostIPC bool
|
||||
HostPID bool
|
||||
@ -52,8 +53,8 @@ type Config struct {
|
||||
}
|
||||
|
||||
// CreateUnschedulablePod with given claims based on node selector
|
||||
func CreateUnschedulablePod(ctx context.Context, client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) (*v1.Pod, error) {
|
||||
pod := MakePod(namespace, nodeSelector, pvclaims, isPrivileged, command)
|
||||
func CreateUnschedulablePod(ctx context.Context, client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, securityLevel admissionapi.Level, command string) (*v1.Pod, error) {
|
||||
pod := MakePod(namespace, nodeSelector, pvclaims, securityLevel, command)
|
||||
pod, err := client.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("pod Create API error: %w", err)
|
||||
@ -73,12 +74,12 @@ func CreateUnschedulablePod(ctx context.Context, client clientset.Interface, nam
|
||||
|
||||
// CreateClientPod defines and creates a pod with a mounted PV. Pod runs infinite loop until killed.
|
||||
func CreateClientPod(ctx context.Context, c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim) (*v1.Pod, error) {
|
||||
return CreatePod(ctx, c, ns, nil, []*v1.PersistentVolumeClaim{pvc}, true, "")
|
||||
return CreatePod(ctx, c, ns, nil, []*v1.PersistentVolumeClaim{pvc}, admissionapi.LevelPrivileged, "")
|
||||
}
|
||||
|
||||
// CreatePod with given claims based on node selector
|
||||
func CreatePod(ctx context.Context, client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) (*v1.Pod, error) {
|
||||
pod := MakePod(namespace, nodeSelector, pvclaims, isPrivileged, command)
|
||||
func CreatePod(ctx context.Context, client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, securityLevel admissionapi.Level, command string) (*v1.Pod, error) {
|
||||
pod := MakePod(namespace, nodeSelector, pvclaims, securityLevel, command)
|
||||
pod, err := client.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("pod Create API error: %w", err)
|
||||
@ -128,7 +129,7 @@ func CreateSecPodWithNodeSelection(ctx context.Context, client clientset.Interfa
|
||||
|
||||
// MakePod returns a pod definition based on the namespace. The pod references the PVC's
|
||||
// name. A slice of BASH commands can be supplied as args to be run by the pod
|
||||
func MakePod(ns string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) *v1.Pod {
|
||||
func MakePod(ns string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, securityLevel admissionapi.Level, command string) *v1.Pod {
|
||||
if len(command) == 0 {
|
||||
command = "trap exit TERM; while true; do sleep 1; done"
|
||||
}
|
||||
@ -147,7 +148,7 @@ func MakePod(ns string, nodeSelector map[string]string, pvclaims []*v1.Persisten
|
||||
Name: "write-pod",
|
||||
Image: GetDefaultTestImage(),
|
||||
Command: GenerateScriptCmd(command),
|
||||
SecurityContext: GenerateContainerSecurityContext(isPrivileged),
|
||||
SecurityContext: GenerateContainerSecurityContext(securityLevel),
|
||||
},
|
||||
},
|
||||
RestartPolicy: v1.RestartPolicyOnFailure,
|
||||
@ -157,6 +158,10 @@ func MakePod(ns string, nodeSelector map[string]string, pvclaims []*v1.Persisten
|
||||
if nodeSelector != nil {
|
||||
podSpec.Spec.NodeSelector = nodeSelector
|
||||
}
|
||||
if securityLevel == admissionapi.LevelRestricted {
|
||||
podSpec = MustMixinRestrictedPodSecurity(podSpec)
|
||||
}
|
||||
|
||||
return podSpec
|
||||
}
|
||||
|
||||
@ -196,6 +201,10 @@ func MakePodSpec(podConfig *Config) *v1.PodSpec {
|
||||
if podConfig.ImageID != imageutils.None {
|
||||
image = podConfig.ImageID
|
||||
}
|
||||
securityLevel := podConfig.SecurityLevel
|
||||
if securityLevel == "" {
|
||||
securityLevel = admissionapi.LevelBaseline
|
||||
}
|
||||
podSpec := &v1.PodSpec{
|
||||
HostIPC: podConfig.HostIPC,
|
||||
HostPID: podConfig.HostPID,
|
||||
@ -205,7 +214,7 @@ func MakePodSpec(podConfig *Config) *v1.PodSpec {
|
||||
Name: "write-pod",
|
||||
Image: GetTestImage(image),
|
||||
Command: GenerateScriptCmd(podConfig.Command),
|
||||
SecurityContext: GenerateContainerSecurityContext(podConfig.IsPrivileged),
|
||||
SecurityContext: GenerateContainerSecurityContext(securityLevel),
|
||||
},
|
||||
},
|
||||
RestartPolicy: v1.RestartPolicyOnFailure,
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go
generated
vendored
@ -30,7 +30,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
apiv1pod "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
|
||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||
@ -180,7 +180,7 @@ func MatchContainerOutput(
|
||||
|
||||
if podErr != nil {
|
||||
// Pod failed. Dump all logs from all containers to see what's wrong
|
||||
_ = apiv1pod.VisitContainers(&podStatus.Spec, apiv1pod.AllFeatureEnabledContainers(), func(c *v1.Container, containerType apiv1pod.ContainerType) bool {
|
||||
_ = podutils.VisitContainers(&podStatus.Spec, podutils.AllContainers, func(c *v1.Container, containerType podutils.ContainerType) bool {
|
||||
logs, err := e2epod.GetPodLogs(ctx, f.ClientSet, ns, podStatus.Name, c.Name)
|
||||
if err != nil {
|
||||
framework.Logf("Failed to get logs from node %q pod %q container %q: %v",
|
||||
|
61
vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go
generated
vendored
61
vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go
generated
vendored
@ -38,8 +38,6 @@ import (
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/onsi/gomega"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
)
|
||||
|
||||
@ -72,6 +70,7 @@ func NewPodClient(f *framework.Framework) *PodClient {
|
||||
return &PodClient{
|
||||
f: f,
|
||||
PodInterface: f.ClientSet.CoreV1().Pods(f.Namespace.Name),
|
||||
namespace: f.Namespace.Name,
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +81,7 @@ func PodClientNS(f *framework.Framework, namespace string) *PodClient {
|
||||
return &PodClient{
|
||||
f: f,
|
||||
PodInterface: f.ClientSet.CoreV1().Pods(namespace),
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,6 +89,7 @@ func PodClientNS(f *framework.Framework, namespace string) *PodClient {
|
||||
type PodClient struct {
|
||||
f *framework.Framework
|
||||
v1core.PodInterface
|
||||
namespace string
|
||||
}
|
||||
|
||||
// Create creates a new pod according to the framework specifications (don't wait for it to start).
|
||||
@ -101,9 +102,8 @@ func (c *PodClient) Create(ctx context.Context, pod *v1.Pod) *v1.Pod {
|
||||
|
||||
// CreateSync creates a new pod according to the framework specifications, and wait for it to start and be running and ready.
|
||||
func (c *PodClient) CreateSync(ctx context.Context, pod *v1.Pod) *v1.Pod {
|
||||
namespace := c.f.Namespace.Name
|
||||
p := c.Create(ctx, pod)
|
||||
framework.ExpectNoError(WaitTimeoutForPodReadyInNamespace(ctx, c.f.ClientSet, p.Name, namespace, framework.PodStartTimeout))
|
||||
framework.ExpectNoError(WaitTimeoutForPodReadyInNamespace(ctx, c.f.ClientSet, p.Name, c.namespace, framework.PodStartTimeout))
|
||||
// Get the newest pod after it becomes running and ready, some status may change after pod created, such as pod ip.
|
||||
p, err := c.Get(ctx, p.Name, metav1.GetOptions{})
|
||||
framework.ExpectNoError(err)
|
||||
@ -151,37 +151,45 @@ func (c *PodClient) Update(ctx context.Context, name string, updateFn func(pod *
|
||||
|
||||
// AddEphemeralContainerSync adds an EphemeralContainer to a pod and waits for it to be running.
|
||||
func (c *PodClient) AddEphemeralContainerSync(ctx context.Context, pod *v1.Pod, ec *v1.EphemeralContainer, timeout time.Duration) error {
|
||||
namespace := c.f.Namespace.Name
|
||||
|
||||
podJS, err := json.Marshal(pod)
|
||||
framework.ExpectNoError(err, "error creating JSON for pod %q", format.Pod(pod))
|
||||
framework.ExpectNoError(err, "error creating JSON for pod %q", FormatPod(pod))
|
||||
|
||||
ecPod := pod.DeepCopy()
|
||||
ecPod.Spec.EphemeralContainers = append(ecPod.Spec.EphemeralContainers, *ec)
|
||||
ecJS, err := json.Marshal(ecPod)
|
||||
framework.ExpectNoError(err, "error creating JSON for pod with ephemeral container %q", format.Pod(pod))
|
||||
framework.ExpectNoError(err, "error creating JSON for pod with ephemeral container %q", FormatPod(pod))
|
||||
|
||||
patch, err := strategicpatch.CreateTwoWayMergePatch(podJS, ecJS, pod)
|
||||
framework.ExpectNoError(err, "error creating patch to add ephemeral container %q", format.Pod(pod))
|
||||
framework.ExpectNoError(err, "error creating patch to add ephemeral container %q", FormatPod(pod))
|
||||
|
||||
// Clients may optimistically attempt to add an ephemeral container to determine whether the EphemeralContainers feature is enabled.
|
||||
if _, err := c.Patch(ctx, pod.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}, "ephemeralcontainers"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
framework.ExpectNoError(WaitForContainerRunning(ctx, c.f.ClientSet, namespace, pod.Name, ec.Name, timeout))
|
||||
framework.ExpectNoError(WaitForContainerRunning(ctx, c.f.ClientSet, c.namespace, pod.Name, ec.Name, timeout))
|
||||
return nil
|
||||
}
|
||||
|
||||
// FormatPod returns a string representing a pod in a consistent human readable format,
|
||||
// with pod name, namespace and pod UID as part of the string.
|
||||
// This code is taken from k/k/pkg/kubelet/util/format/pod.go to remove
|
||||
// e2e framework -> k/k/pkg/kubelet dependency.
|
||||
func FormatPod(pod *v1.Pod) string {
|
||||
if pod == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("%s_%s(%s)", pod.Name, pod.Namespace, pod.UID)
|
||||
}
|
||||
|
||||
// DeleteSync deletes the pod and wait for the pod to disappear for `timeout`. If the pod doesn't
|
||||
// disappear before the timeout, it will fail the test.
|
||||
func (c *PodClient) DeleteSync(ctx context.Context, name string, options metav1.DeleteOptions, timeout time.Duration) {
|
||||
namespace := c.f.Namespace.Name
|
||||
err := c.Delete(ctx, name, options)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
framework.Failf("Failed to delete pod %q: %v", name, err)
|
||||
}
|
||||
framework.ExpectNoError(WaitForPodNotFoundInNamespace(ctx, c.f.ClientSet, name, namespace, timeout), "wait for pod %q to disappear", name)
|
||||
framework.ExpectNoError(WaitForPodNotFoundInNamespace(ctx, c.f.ClientSet, name, c.namespace, timeout), "wait for pod %q to disappear", name)
|
||||
}
|
||||
|
||||
// mungeSpec apply test-suite specific transformations to the pod spec.
|
||||
@ -223,8 +231,7 @@ func (c *PodClient) mungeSpec(pod *v1.Pod) {
|
||||
// WaitForSuccess waits for pod to succeed.
|
||||
// TODO(random-liu): Move pod wait function into this file
|
||||
func (c *PodClient) WaitForSuccess(ctx context.Context, name string, timeout time.Duration) {
|
||||
f := c.f
|
||||
gomega.Expect(WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout,
|
||||
gomega.Expect(WaitForPodCondition(ctx, c.f.ClientSet, c.namespace, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout,
|
||||
func(pod *v1.Pod) (bool, error) {
|
||||
switch pod.Status.Phase {
|
||||
case v1.PodFailed:
|
||||
@ -240,8 +247,7 @@ func (c *PodClient) WaitForSuccess(ctx context.Context, name string, timeout tim
|
||||
|
||||
// WaitForFinish waits for pod to finish running, regardless of success or failure.
|
||||
func (c *PodClient) WaitForFinish(ctx context.Context, name string, timeout time.Duration) {
|
||||
f := c.f
|
||||
gomega.Expect(WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout,
|
||||
gomega.Expect(WaitForPodCondition(ctx, c.f.ClientSet, c.namespace, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout,
|
||||
func(pod *v1.Pod) (bool, error) {
|
||||
switch pod.Status.Phase {
|
||||
case v1.PodFailed:
|
||||
@ -303,10 +309,29 @@ func (c *PodClient) PodIsReady(ctx context.Context, name string) bool {
|
||||
return podutils.IsPodReady(pod)
|
||||
}
|
||||
|
||||
// RemovePodFinalizer removes the pod's finalizer
|
||||
// RemoveString returns a newly created []string that contains all items from slice
|
||||
// that are not equal to s.
|
||||
// This code is taken from k/k/pkg/util/slice/slice.go to remove
|
||||
// e2e/framework/pod -> k/k/pkg/util/slice dependency.
|
||||
func removeString(slice []string, s string) []string {
|
||||
newSlice := make([]string, 0)
|
||||
for _, item := range slice {
|
||||
if item != s {
|
||||
newSlice = append(newSlice, item)
|
||||
}
|
||||
}
|
||||
if len(newSlice) == 0 {
|
||||
// Sanitize for unit tests so we don't need to distinguish empty array
|
||||
// and nil.
|
||||
return nil
|
||||
}
|
||||
return newSlice
|
||||
}
|
||||
|
||||
// RemoveFinalizer removes the pod's finalizer
|
||||
func (c *PodClient) RemoveFinalizer(ctx context.Context, podName string, finalizerName string) {
|
||||
framework.Logf("Removing pod's %q finalizer: %q", podName, finalizerName)
|
||||
c.Update(ctx, podName, func(pod *v1.Pod) {
|
||||
pod.ObjectMeta.Finalizers = slice.RemoveString(pod.ObjectMeta.Finalizers, finalizerName, nil)
|
||||
pod.ObjectMeta.Finalizers = removeString(pod.ObjectMeta.Finalizers, finalizerName)
|
||||
})
|
||||
}
|
||||
|
20
vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go
generated
vendored
20
vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go
generated
vendored
@ -20,6 +20,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/onsi/gomega"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@ -111,12 +112,25 @@ func GeneratePodSecurityContext(fsGroup *int64, seLinuxOptions *v1.SELinuxOption
|
||||
// GenerateContainerSecurityContext generates the corresponding container security context with the given inputs
|
||||
// If the Node OS is windows, currently we will ignore the inputs and return nil.
|
||||
// TODO: Will modify it after windows has its own security context
|
||||
func GenerateContainerSecurityContext(privileged bool) *v1.SecurityContext {
|
||||
func GenerateContainerSecurityContext(level psaapi.Level) *v1.SecurityContext {
|
||||
if NodeOSDistroIs("windows") {
|
||||
return nil
|
||||
}
|
||||
return &v1.SecurityContext{
|
||||
Privileged: &privileged,
|
||||
|
||||
switch level {
|
||||
case psaapi.LevelBaseline:
|
||||
return &v1.SecurityContext{
|
||||
Privileged: pointer.Bool(false),
|
||||
}
|
||||
case psaapi.LevelPrivileged:
|
||||
return &v1.SecurityContext{
|
||||
Privileged: pointer.Bool(true),
|
||||
}
|
||||
case psaapi.LevelRestricted:
|
||||
return GetRestrictedContainerSecurityContext()
|
||||
default:
|
||||
ginkgo.Fail(fmt.Sprintf("unknown k8s.io/pod-security-admission/policy.Level %q", level))
|
||||
panic("not reached")
|
||||
}
|
||||
}
|
||||
|
||||
|
5
vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go
generated
vendored
5
vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go
generated
vendored
@ -37,7 +37,6 @@ import (
|
||||
apitypes "k8s.io/apimachinery/pkg/types"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
testutils "k8s.io/kubernetes/test/utils"
|
||||
"k8s.io/kubernetes/test/utils/format"
|
||||
@ -332,7 +331,7 @@ func WaitForPods(ctx context.Context, c clientset.Interface, ns string, opts met
|
||||
// RunningReady checks whether pod p's phase is running and it has a ready
|
||||
// condition of status true.
|
||||
func RunningReady(p *v1.Pod) bool {
|
||||
return p.Status.Phase == v1.PodRunning && podutil.IsPodReady(p)
|
||||
return p.Status.Phase == v1.PodRunning && podutils.IsPodReady(p)
|
||||
}
|
||||
|
||||
// WaitForPodsRunning waits for a given `timeout` to evaluate if a certain amount of pods in given `ns` are running.
|
||||
@ -542,7 +541,7 @@ func WaitForPodNotFoundInNamespace(ctx context.Context, c clientset.Interface, p
|
||||
return nil
|
||||
}
|
||||
|
||||
// PodsResponding waits for the pods to response.
|
||||
// WaitForPodsResponding waits for the pods to response.
|
||||
func WaitForPodsResponding(ctx context.Context, c clientset.Interface, ns string, controllerName string, wantName bool, timeout time.Duration, pods *v1.PodList) error {
|
||||
if timeout == 0 {
|
||||
timeout = podRespondingTimeout
|
||||
|
2
vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go
generated
vendored
@ -78,7 +78,7 @@ type pvcval struct{}
|
||||
type PVCMap map[types.NamespacedName]pvcval
|
||||
|
||||
// PersistentVolumeConfig is consumed by MakePersistentVolume() to generate a PV object
|
||||
// for varying storage options (NFS, ceph, glusterFS, etc.).
|
||||
// for varying storage options (NFS, ceph, etc.).
|
||||
// (+optional) prebind holds a pre-bound PVC
|
||||
// Example pvSource:
|
||||
//
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/ssh/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/ssh/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
18
vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go
generated
vendored
18
vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go
generated
vendored
@ -41,7 +41,6 @@ import (
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||
"k8s.io/kubernetes/test/e2e/framework/internal/junit"
|
||||
"k8s.io/kubernetes/test/utils/image"
|
||||
"k8s.io/kubernetes/test/utils/kubeconfig"
|
||||
@ -244,8 +243,6 @@ type NodeTestContextType struct {
|
||||
NodeConformance bool
|
||||
// PrepullImages indicates whether node e2e framework should prepull images.
|
||||
PrepullImages bool
|
||||
// KubeletConfig is the kubelet configuration the test is running against.
|
||||
KubeletConfig kubeletconfig.KubeletConfiguration
|
||||
// ImageDescription is the description of the image on which the test is running.
|
||||
ImageDescription string
|
||||
// RuntimeConfig is a map of API server runtime configuration values.
|
||||
@ -350,18 +347,13 @@ func RegisterCommonFlags(flags *flag.FlagSet) {
|
||||
flags.StringVar(&TestContext.ReportDir, "report-dir", "", "Path to the directory where the simplified JUnit XML reports and other tests results should be saved. Default is empty, which doesn't generate these reports. If ginkgo's -junit-report parameter is used, that parameter instead of -report-dir determines the location of a single JUnit report.")
|
||||
flags.BoolVar(&TestContext.ReportCompleteGinkgo, "report-complete-ginkgo", false, "Enables writing a complete test report as Ginkgo JSON to <report dir>/ginkgo/report.json. Ignored if --report-dir is not set.")
|
||||
flags.BoolVar(&TestContext.ReportCompleteJUnit, "report-complete-junit", false, "Enables writing a complete test report as JUnit XML to <report dir>/ginkgo/report.json. Ignored if --report-dir is not set.")
|
||||
flags.StringVar(&TestContext.ContainerRuntimeEndpoint, "container-runtime-endpoint", "unix:///var/run/containerd/containerd.sock", "The container runtime endpoint of cluster VM instances.")
|
||||
flags.StringVar(&TestContext.ContainerRuntimeProcessName, "container-runtime-process-name", "dockerd", "The name of the container runtime process.")
|
||||
flags.StringVar(&TestContext.ContainerRuntimePidFile, "container-runtime-pid-file", "/var/run/docker.pid", "The pid file of the container runtime.")
|
||||
flags.StringVar(&TestContext.SystemdServices, "systemd-services", "docker", "The comma separated list of systemd services the framework will dump logs for.")
|
||||
flags.StringVar(&TestContext.ContainerRuntimeEndpoint, "container-runtime-endpoint", "unix:///run/containerd/containerd.sock", "The container runtime endpoint of cluster VM instances.")
|
||||
flags.StringVar(&TestContext.ContainerRuntimeProcessName, "container-runtime-process-name", "containerd", "The name of the container runtime process.")
|
||||
flags.StringVar(&TestContext.ContainerRuntimePidFile, "container-runtime-pid-file", "/run/containerd/containerd.pid", "The pid file of the container runtime.")
|
||||
flags.StringVar(&TestContext.SystemdServices, "systemd-services", "containerd*", "The comma separated list of systemd services the framework will dump logs for.")
|
||||
flags.BoolVar(&TestContext.DumpSystemdJournal, "dump-systemd-journal", false, "Whether to dump the full systemd journal.")
|
||||
flags.StringVar(&TestContext.ImageServiceEndpoint, "image-service-endpoint", "", "The image service endpoint of cluster VM instances.")
|
||||
// TODO: remove the node-role.kubernetes.io/master taint in 1.25 or later.
|
||||
// The change will likely require an action for some users that do not
|
||||
// use k8s originated tools like kubeadm or kOps for creating clusters
|
||||
// and taint their control plane nodes with "master", expecting the test
|
||||
// suite to work with this legacy non-blocking taint.
|
||||
flags.StringVar(&TestContext.NonblockingTaints, "non-blocking-taints", `node-role.kubernetes.io/control-plane,node-role.kubernetes.io/master`, "Nodes with taints in this comma-delimited list will not block the test framework from starting tests. The default taint 'node-role.kubernetes.io/master' is DEPRECATED and will be removed from the list in a future release.")
|
||||
flags.StringVar(&TestContext.NonblockingTaints, "non-blocking-taints", `node-role.kubernetes.io/control-plane`, "Nodes with taints in this comma-delimited list will not block the test framework from starting tests.")
|
||||
|
||||
flags.BoolVar(&TestContext.ListImages, "list-images", false, "If true, will show list of images used for running tests.")
|
||||
flags.StringVar(&TestContext.KubectlPath, "kubectl-path", "kubectl", "The kubectl binary to use. For development, you might use 'cluster/kubectl.sh' here.")
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/.import-restrictions
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/.import-restrictions
generated
vendored
@ -1,9 +1,12 @@
|
||||
# This E2E framework sub-package is currently allowed to use arbitrary
|
||||
# dependencies, therefore we need to override the restrictions from
|
||||
# the parent .import-restrictions file.
|
||||
# dependencies except of k/k/pkg, therefore we need to override the
|
||||
# restrictions from the parent .import-restrictions file.
|
||||
#
|
||||
# At some point it may become useful to also check this package's
|
||||
# dependencies more careful.
|
||||
rules:
|
||||
- selectorRegexp: "^k8s[.]io/kubernetes/pkg"
|
||||
allowedPrefixes: []
|
||||
|
||||
- selectorRegexp: ""
|
||||
allowedPrefixes: [ "" ]
|
||||
|
45
vendor/k8s.io/kubernetes/test/e2e/framework/util.go
generated
vendored
45
vendor/k8s.io/kubernetes/test/e2e/framework/util.go
generated
vendored
@ -36,6 +36,7 @@ import (
|
||||
"github.com/onsi/gomega"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
discoveryv1 "k8s.io/api/discovery/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
@ -420,20 +421,37 @@ func CheckTestingNSDeletedExcept(ctx context.Context, c clientset.Interface, ski
|
||||
}
|
||||
|
||||
// WaitForServiceEndpointsNum waits until the amount of endpoints that implement service to expectNum.
|
||||
// Some components use EndpointSlices other Endpoints, we must verify that both objects meet the requirements.
|
||||
func WaitForServiceEndpointsNum(ctx context.Context, c clientset.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error {
|
||||
return wait.PollWithContext(ctx, interval, timeout, func(ctx context.Context) (bool, error) {
|
||||
Logf("Waiting for amount of service:%s endpoints to be %d", serviceName, expectNum)
|
||||
list, err := c.CoreV1().Endpoints(namespace).List(ctx, metav1.ListOptions{})
|
||||
endpoint, err := c.CoreV1().Endpoints(namespace).Get(ctx, serviceName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
Logf("Unexpected error trying to get Endpoints for %s : %v", serviceName, err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, e := range list.Items {
|
||||
if e.Name == serviceName && countEndpointsNum(&e) == expectNum {
|
||||
return true, nil
|
||||
}
|
||||
if countEndpointsNum(endpoint) != expectNum {
|
||||
Logf("Unexpected number of Endpoints, got %d, expected %d", countEndpointsNum(endpoint), expectNum)
|
||||
return false, nil
|
||||
}
|
||||
return false, nil
|
||||
|
||||
esList, err := c.DiscoveryV1().EndpointSlices(namespace).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", discoveryv1.LabelServiceName, serviceName)})
|
||||
if err != nil {
|
||||
Logf("Unexpected error trying to get EndpointSlices for %s : %v", serviceName, err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(esList.Items) == 0 {
|
||||
Logf("Waiting for at least 1 EndpointSlice to exist")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if countEndpointsSlicesNum(esList) != expectNum {
|
||||
Logf("Unexpected number of Endpoints on Slices, got %d, expected %d", countEndpointsSlicesNum(esList), expectNum)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
}
|
||||
|
||||
@ -445,6 +463,19 @@ func countEndpointsNum(e *v1.Endpoints) int {
|
||||
return num
|
||||
}
|
||||
|
||||
func countEndpointsSlicesNum(epList *discoveryv1.EndpointSliceList) int {
|
||||
// EndpointSlices can contain the same address on multiple Slices
|
||||
addresses := sets.Set[string]{}
|
||||
for _, epSlice := range epList.Items {
|
||||
for _, ep := range epSlice.Endpoints {
|
||||
if len(ep.Addresses) > 0 {
|
||||
addresses.Insert(ep.Addresses[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
return addresses.Len()
|
||||
}
|
||||
|
||||
// restclientConfig returns a config holds the information needed to build connection to kubernetes clusters.
|
||||
func restclientConfig(kubeContext string) (*clientcmdapi.Config, error) {
|
||||
Logf(">>> kubeConfig: %s", TestContext.KubeConfig)
|
||||
|
20
vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go
generated
vendored
20
vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go
generated
vendored
@ -18,14 +18,14 @@ limitations under the License.
|
||||
* This test checks that various VolumeSources are working.
|
||||
*
|
||||
* There are two ways, how to test the volumes:
|
||||
* 1) With containerized server (NFS, Ceph, Gluster, iSCSI, ...)
|
||||
* 1) With containerized server (NFS, Ceph, iSCSI, ...)
|
||||
* The test creates a server pod, exporting simple 'index.html' file.
|
||||
* Then it uses appropriate VolumeSource to import this file into a client pod
|
||||
* and checks that the pod can see the file. It does so by importing the file
|
||||
* into web server root and loadind the index.html from it.
|
||||
* into web server root and loading the index.html from it.
|
||||
*
|
||||
* These tests work only when privileged containers are allowed, exporting
|
||||
* various filesystems (NFS, GlusterFS, ...) usually needs some mounting or
|
||||
* various filesystems (ex: NFS) usually needs some mounting or
|
||||
* other privileged magic in the server pod.
|
||||
*
|
||||
* Note that the server containers are for testing purposes only and should not
|
||||
@ -59,6 +59,7 @@ import (
|
||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||
e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
|
||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||
admissionapi "k8s.io/pod-security-admission/api"
|
||||
uexec "k8s.io/utils/exec"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
@ -87,7 +88,7 @@ const (
|
||||
VolumeServerPodStartupTimeout = 3 * time.Minute
|
||||
|
||||
// PodCleanupTimeout is a waiting period for pod to be cleaned up and unmount its volumes so we
|
||||
// don't tear down containers with NFS/Ceph/Gluster server too early.
|
||||
// don't tear down containers with NFS/Ceph server too early.
|
||||
PodCleanupTimeout = 20 * time.Second
|
||||
)
|
||||
|
||||
@ -398,8 +399,9 @@ func runVolumeTesterPod(ctx context.Context, client clientset.Interface, timeout
|
||||
When SELinux is enabled on the host, client-pod can not read the content, with permission denied.
|
||||
Invoking client-pod as privileged, so that it can access the volume content, even when SELinux is enabled on the host.
|
||||
*/
|
||||
if config.Prefix == "hostpathsymlink" || config.Prefix == "hostpath" {
|
||||
privileged = true
|
||||
securityLevel := admissionapi.LevelBaseline // TODO (#118184): also support LevelRestricted
|
||||
if privileged || config.Prefix == "hostpathsymlink" || config.Prefix == "hostpath" {
|
||||
securityLevel = admissionapi.LevelPrivileged
|
||||
}
|
||||
command = "while true ; do sleep 2; done "
|
||||
seLinuxOptions := &v1.SELinuxOptions{Level: "s0:c0,c1"}
|
||||
@ -443,9 +445,9 @@ func runVolumeTesterPod(ctx context.Context, client clientset.Interface, timeout
|
||||
// a privileged container, so we don't go privileged for block volumes.
|
||||
// https://github.com/moby/moby/issues/35991
|
||||
if privileged && test.Mode == v1.PersistentVolumeBlock {
|
||||
privileged = false
|
||||
securityLevel = admissionapi.LevelBaseline
|
||||
}
|
||||
clientPod.Spec.Containers[0].SecurityContext = e2epod.GenerateContainerSecurityContext(privileged)
|
||||
clientPod.Spec.Containers[0].SecurityContext = e2epod.GenerateContainerSecurityContext(securityLevel)
|
||||
|
||||
if test.Mode == v1.PersistentVolumeBlock {
|
||||
clientPod.Spec.Containers[0].VolumeDevices = append(clientPod.Spec.Containers[0].VolumeDevices, v1.VolumeDevice{
|
||||
@ -620,7 +622,7 @@ func generateWriteCmd(content, path string) []string {
|
||||
return commands
|
||||
}
|
||||
|
||||
// generateReadBlockCmd generates the corresponding command lines to read from a block device with the given file path.
|
||||
// GenerateReadBlockCmd generates the corresponding command lines to read from a block device with the given file path.
|
||||
func GenerateReadBlockCmd(fullPath string, numberOfCharacters int) []string {
|
||||
var commands []string
|
||||
commands = []string{"head", "-c", strconv.Itoa(numberOfCharacters), fullPath}
|
||||
|
11
vendor/k8s.io/kubernetes/test/utils/deployment.go
generated
vendored
11
vendor/k8s.io/kubernetes/test/utils/deployment.go
generated
vendored
@ -21,11 +21,10 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
apps "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/dump"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
@ -37,7 +36,7 @@ type LogfFn func(format string, args ...interface{})
|
||||
|
||||
func LogReplicaSetsOfDeployment(deployment *apps.Deployment, allOldRSs []*apps.ReplicaSet, newRS *apps.ReplicaSet, logf LogfFn) {
|
||||
if newRS != nil {
|
||||
logf(spew.Sprintf("New ReplicaSet %q of Deployment %q:\n%+v", newRS.Name, deployment.Name, *newRS))
|
||||
logf("New ReplicaSet %q of Deployment %q:\n%s", newRS.Name, deployment.Name, dump.Pretty(*newRS))
|
||||
} else {
|
||||
logf("New ReplicaSet of Deployment %q is nil.", deployment.Name)
|
||||
}
|
||||
@ -45,7 +44,7 @@ func LogReplicaSetsOfDeployment(deployment *apps.Deployment, allOldRSs []*apps.R
|
||||
logf("All old ReplicaSets of Deployment %q:", deployment.Name)
|
||||
}
|
||||
for i := range allOldRSs {
|
||||
logf(spew.Sprintf("%+v", *allOldRSs[i]))
|
||||
logf(dump.Pretty(*allOldRSs[i]))
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +64,7 @@ func LogPodsOfDeployment(c clientset.Interface, deployment *apps.Deployment, rsL
|
||||
if podutil.IsPodAvailable(&pod, minReadySeconds, metav1.Now()) {
|
||||
availability = "available"
|
||||
}
|
||||
logf(spew.Sprintf("Pod %q is %s:\n%+v", pod.Name, availability, pod))
|
||||
logf("Pod %q is %s:\n%s", pod.Name, availability, dump.Pretty(pod))
|
||||
}
|
||||
}
|
||||
|
||||
|
18
vendor/k8s.io/kubernetes/test/utils/image/manifest.go
generated
vendored
18
vendor/k8s.io/kubernetes/test/utils/image/manifest.go
generated
vendored
@ -173,8 +173,6 @@ const (
|
||||
DistrolessIptables
|
||||
// Etcd image
|
||||
Etcd
|
||||
// GlusterDynamicProvisioner image
|
||||
GlusterDynamicProvisioner
|
||||
// Httpd image
|
||||
Httpd
|
||||
// HttpdNew image
|
||||
@ -226,8 +224,6 @@ const (
|
||||
VolumeNFSServer
|
||||
// VolumeISCSIServer image
|
||||
VolumeISCSIServer
|
||||
// VolumeGlusterServer image
|
||||
VolumeGlusterServer
|
||||
// VolumeRBDServer image
|
||||
VolumeRBDServer
|
||||
// WindowsServer image
|
||||
@ -236,7 +232,7 @@ const (
|
||||
|
||||
func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config) {
|
||||
configs := map[ImageID]Config{}
|
||||
configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.43"}
|
||||
configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.45"}
|
||||
configs[AgnhostPrivate] = Config{list.PrivateRegistry, "agnhost", "2.6"}
|
||||
configs[AuthenticatedAlpine] = Config{list.GcAuthenticatedRegistry, "alpine", "3.7"}
|
||||
configs[AuthenticatedWindowsNanoServer] = Config{list.GcAuthenticatedRegistry, "windows-nanoserver", "v1"}
|
||||
@ -244,10 +240,9 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config
|
||||
configs[AppArmorLoader] = Config{list.PromoterE2eRegistry, "apparmor-loader", "1.4"}
|
||||
configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.29-4"}
|
||||
configs[CudaVectorAdd] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "1.0"}
|
||||
configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.2"}
|
||||
configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.2.3"}
|
||||
configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.7-0"}
|
||||
configs[GlusterDynamicProvisioner] = Config{list.PromoterE2eRegistry, "glusterdynamic-provisioner", "v1.3"}
|
||||
configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.3"}
|
||||
configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.2.7"}
|
||||
configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.9-0"}
|
||||
configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"}
|
||||
configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"}
|
||||
configs[InvalidRegistryImage] = Config{list.InvalidRegistry, "alpine", "3.1"}
|
||||
@ -273,9 +268,8 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config
|
||||
configs[ResourceConsumer] = Config{list.PromoterE2eRegistry, "resource-consumer", "1.13"}
|
||||
configs[SdDummyExporter] = Config{list.GcRegistry, "sd-dummy-exporter", "v0.2.0"}
|
||||
configs[VolumeNFSServer] = Config{list.PromoterE2eRegistry, "volume/nfs", "1.3"}
|
||||
configs[VolumeISCSIServer] = Config{list.PromoterE2eRegistry, "volume/iscsi", "2.3"}
|
||||
configs[VolumeGlusterServer] = Config{list.PromoterE2eRegistry, "volume/gluster", "1.3"}
|
||||
configs[VolumeRBDServer] = Config{list.PromoterE2eRegistry, "volume/rbd", "1.0.4"}
|
||||
configs[VolumeISCSIServer] = Config{list.PromoterE2eRegistry, "volume/iscsi", "2.6"}
|
||||
configs[VolumeRBDServer] = Config{list.PromoterE2eRegistry, "volume/rbd", "1.0.6"}
|
||||
configs[WindowsServer] = Config{list.MicrosoftRegistry, "windows", "1809"}
|
||||
|
||||
// This adds more config entries. Those have no pre-defined ImageID number,
|
||||
|
12
vendor/k8s.io/kubernetes/test/utils/paths.go
generated
vendored
12
vendor/k8s.io/kubernetes/test/utils/paths.go
generated
vendored
@ -27,6 +27,11 @@ import (
|
||||
|
||||
// GetK8sRootDir returns the root directory for kubernetes, if present in the gopath.
|
||||
func GetK8sRootDir() (string, error) {
|
||||
dir := os.Getenv("KUBE_ROOT")
|
||||
if len(dir) > 0 {
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
dir, err := RootDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -59,12 +64,17 @@ func RootDir() (string, error) {
|
||||
}
|
||||
|
||||
// GetK8sBuildOutputDir returns the build output directory for k8s
|
||||
func GetK8sBuildOutputDir() (string, error) {
|
||||
// For dockerized build, targetArch (eg: 'linux/arm64', 'linux/amd64') must be explicitly specified
|
||||
// For non dockerized build, targetArch is ignored
|
||||
func GetK8sBuildOutputDir(isDockerizedBuild bool, targetArch string) (string, error) {
|
||||
k8sRoot, err := GetK8sRootDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
buildOutputDir := filepath.Join(k8sRoot, "_output/local/go/bin")
|
||||
if isDockerizedBuild {
|
||||
buildOutputDir = filepath.Join(k8sRoot, "_output/dockerized/bin/", targetArch)
|
||||
}
|
||||
if _, err := os.Stat(buildOutputDir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
49
vendor/k8s.io/kubernetes/test/utils/runners.go
generated
vendored
49
vendor/k8s.io/kubernetes/test/utils/runners.go
generated
vendored
@ -183,8 +183,11 @@ type RCConfig struct {
|
||||
|
||||
ServiceAccountTokenProjections int
|
||||
|
||||
//Additional containers to run in the pod
|
||||
// Additional containers to run in the pod
|
||||
AdditionalContainers []v1.Container
|
||||
|
||||
// Security context for created pods
|
||||
SecurityContext *v1.SecurityContext
|
||||
}
|
||||
|
||||
func (rc *RCConfig) RCConfigLog(fmt string, args ...interface{}) {
|
||||
@ -335,11 +338,12 @@ func (config *DeploymentConfig) create() error {
|
||||
TerminationGracePeriodSeconds: config.getTerminationGracePeriodSeconds(nil),
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
Lifecycle: config.Lifecycle,
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
Lifecycle: config.Lifecycle,
|
||||
SecurityContext: config.SecurityContext,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -421,11 +425,12 @@ func (config *ReplicaSetConfig) create() error {
|
||||
TerminationGracePeriodSeconds: config.getTerminationGracePeriodSeconds(nil),
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
Lifecycle: config.Lifecycle,
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
Lifecycle: config.Lifecycle,
|
||||
SecurityContext: config.SecurityContext,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -499,10 +504,11 @@ func (config *JobConfig) create() error {
|
||||
TerminationGracePeriodSeconds: config.getTerminationGracePeriodSeconds(nil),
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Lifecycle: config.Lifecycle,
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Lifecycle: config.Lifecycle,
|
||||
SecurityContext: config.SecurityContext,
|
||||
},
|
||||
},
|
||||
RestartPolicy: v1.RestartPolicyOnFailure,
|
||||
@ -612,12 +618,13 @@ func (config *RCConfig) create() error {
|
||||
Affinity: config.Affinity,
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
ReadinessProbe: config.ReadinessProbe,
|
||||
Lifecycle: config.Lifecycle,
|
||||
Name: config.Name,
|
||||
Image: config.Image,
|
||||
Command: config.Command,
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
ReadinessProbe: config.ReadinessProbe,
|
||||
Lifecycle: config.Lifecycle,
|
||||
SecurityContext: config.SecurityContext,
|
||||
},
|
||||
},
|
||||
DNSPolicy: *config.DNSPolicy,
|
||||
|
Reference in New Issue
Block a user