Compare commits

..

8 Commits

Author SHA1 Message Date
Kubernetes Publisher
7c4f8c88f6 Update dependencies to v0.27.2 tag 2023-05-18 01:57:04 +00:00
Kubernetes Publisher
015caa2eed Merge pull request #117708 from Jefftree/automated-cherry-pick-of-#117705-upstream-release-1.27
Automated cherry pick of #117705: Update kube-openapi to fix race

Kubernetes-commit: 7d93cc600f4c6dbd5c0b9e37ae7f351cfc59fde7
2023-05-02 17:54:10 +00:00
Jefftree
fb5347d849 Update kube-openapi to fix race
Kubernetes-commit: 86904a7c580d369edc60c5807ef1377d1ff647d2
2023-05-01 17:19:03 +00:00
Kubernetes Publisher
353c489f83 Merge pull request #117685 from ardaguclu/automated-cherry-pick-of-#117495-upstream-release-1.27
Automated cherry pick of #117495: Use absolute path instead requestURI in openapiv3 discovery

Kubernetes-commit: 110415e329c4aabdff9fb4eed7a5d6aa064e7a04
2023-04-29 10:12:16 -07:00
Arda Güçlü
6ce3e7e915 Use absolute path instead requestURI in openapiv3 discovery
Currently, openapiv3 discovery uses requestURI to discover resources.
However, that does not work when the rest endpoint contains prefixes
(e.g. `http://localhost/test-endpoint/`).
Because requestURI overwrites prefixes also in rest endpoint
(e.g. `http://localhost/openapiv3/apis/apps/v1`).

Since `absPath` keeps the prefixes in the rest endpoint,
this PR changes to absPath instead requestURI.

Kubernetes-commit: ee1d7eb5d82f3b2a76afc57bc33bc7e08c34bf27
2023-04-20 09:53:28 +03:00
Kubernetes Publisher
aab9b0a45a Merge pull request #117637 from seans3/automated-cherry-pick-of-#117571-origin-release-1.27
Automated cherry pick of #117571: Refactors discovery content-type and helper functions

Kubernetes-commit: c766f936b7ada04e76c38671c30ceec6df1b5239
2023-04-27 10:30:48 +00:00
Sean Sullivan
a16d525506 Refactors discovery content-type and helper functions
Kubernetes-commit: 3ce0c108fe9587be2e5195ad872578877970a7a9
2023-04-24 17:40:07 -07:00
Kubernetes Publisher
559da627e8 Merge remote-tracking branch 'origin/master' into release-1.27
Kubernetes-commit: 0d6e44998fe1c0a21d0aba1327f55d60ae8a7c2d
2023-03-27 18:31:52 +00:00
102 changed files with 1959 additions and 2405 deletions

6
OWNERS
View File

@@ -3,23 +3,21 @@
approvers:
- caesarxuchao
- deads2k
- lavalamp
- liggitt
- smarterclayton
- sttts
- yliaog
- jpbetz
reviewers:
- aojea
- apelisse
- caesarxuchao
- deads2k
- jpbetz
- lavalamp
- liggitt
- soltysh
- sttts
- yliaog
- jpbetz
labels:
- sig/api-machinery
emeritus_approvers:
- lavalamp

View File

@@ -18,18 +18,11 @@ limitations under the License.
package v1alpha1
import (
v1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
)
// ParamRefApplyConfiguration represents an declarative configuration of the ParamRef type for use
// with apply.
type ParamRefApplyConfiguration struct {
Name *string `json:"name,omitempty"`
Namespace *string `json:"namespace,omitempty"`
Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"`
ParameterNotFoundAction *v1alpha1.ParameterNotFoundActionType `json:"parameterNotFoundAction,omitempty"`
Name *string `json:"name,omitempty"`
Namespace *string `json:"namespace,omitempty"`
}
// ParamRefApplyConfiguration constructs an declarative configuration of the ParamRef type for use with
@@ -53,19 +46,3 @@ func (b *ParamRefApplyConfiguration) WithNamespace(value string) *ParamRefApplyC
b.Namespace = &value
return b
}
// WithSelector sets the Selector field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Selector field is set to the value of the last call.
func (b *ParamRefApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *ParamRefApplyConfiguration {
b.Selector = value
return b
}
// WithParameterNotFoundAction sets the ParameterNotFoundAction field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ParameterNotFoundAction field is set to the value of the last call.
func (b *ParamRefApplyConfiguration) WithParameterNotFoundAction(value v1alpha1.ParameterNotFoundActionType) *ParamRefApplyConfiguration {
b.ParameterNotFoundAction = &value
return b
}

View File

@@ -31,7 +31,6 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct {
FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"`
AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"`
MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"`
Variables []VariableApplyConfiguration `json:"variables,omitempty"`
}
// ValidatingAdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicySpec type for use with
@@ -102,16 +101,3 @@ func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithMatchConditions(va
}
return b
}
// WithVariables adds the given value to the Variables field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Variables field.
func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithVariables(values ...*VariableApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithVariables")
}
b.Variables = append(b.Variables, *values[i])
}
return b
}

View File

@@ -1,48 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1alpha1
// VariableApplyConfiguration represents an declarative configuration of the Variable type for use
// with apply.
type VariableApplyConfiguration struct {
Name *string `json:"name,omitempty"`
Expression *string `json:"expression,omitempty"`
}
// VariableApplyConfiguration constructs an declarative configuration of the Variable type for use with
// apply.
func Variable() *VariableApplyConfiguration {
return &VariableApplyConfiguration{}
}
// WithName sets the Name field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Name field is set to the value of the last call.
func (b *VariableApplyConfiguration) WithName(value string) *VariableApplyConfiguration {
b.Name = &value
return b
}
// WithExpression sets the Expression field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Expression field is set to the value of the last call.
func (b *VariableApplyConfiguration) WithExpression(value string) *VariableApplyConfiguration {
b.Expression = &value
return b
}

View File

@@ -24,7 +24,6 @@ type ServerStorageVersionApplyConfiguration struct {
APIServerID *string `json:"apiServerID,omitempty"`
EncodingVersion *string `json:"encodingVersion,omitempty"`
DecodableVersions []string `json:"decodableVersions,omitempty"`
ServedVersions []string `json:"servedVersions,omitempty"`
}
// ServerStorageVersionApplyConfiguration constructs an declarative configuration of the ServerStorageVersion type for use with
@@ -58,13 +57,3 @@ func (b *ServerStorageVersionApplyConfiguration) WithDecodableVersions(values ..
}
return b
}
// WithServedVersions adds the given value to the ServedVersions field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the ServedVersions field.
func (b *ServerStorageVersionApplyConfiguration) WithServedVersions(values ...string) *ServerStorageVersionApplyConfiguration {
for i := range values {
b.ServedVersions = append(b.ServedVersions, values[i])
}
return b
}

View File

@@ -32,15 +32,12 @@ type JobSpecApplyConfiguration struct {
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
PodFailurePolicy *PodFailurePolicyApplyConfiguration `json:"podFailurePolicy,omitempty"`
BackoffLimit *int32 `json:"backoffLimit,omitempty"`
BackoffLimitPerIndex *int32 `json:"backoffLimitPerIndex,omitempty"`
MaxFailedIndexes *int32 `json:"maxFailedIndexes,omitempty"`
Selector *metav1.LabelSelectorApplyConfiguration `json:"selector,omitempty"`
ManualSelector *bool `json:"manualSelector,omitempty"`
Template *corev1.PodTemplateSpecApplyConfiguration `json:"template,omitempty"`
TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"`
CompletionMode *batchv1.CompletionMode `json:"completionMode,omitempty"`
Suspend *bool `json:"suspend,omitempty"`
PodReplacementPolicy *batchv1.PodReplacementPolicy `json:"podReplacementPolicy,omitempty"`
}
// JobSpecApplyConfiguration constructs an declarative configuration of the JobSpec type for use with
@@ -89,22 +86,6 @@ func (b *JobSpecApplyConfiguration) WithBackoffLimit(value int32) *JobSpecApplyC
return b
}
// WithBackoffLimitPerIndex sets the BackoffLimitPerIndex field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BackoffLimitPerIndex field is set to the value of the last call.
func (b *JobSpecApplyConfiguration) WithBackoffLimitPerIndex(value int32) *JobSpecApplyConfiguration {
b.BackoffLimitPerIndex = &value
return b
}
// WithMaxFailedIndexes sets the MaxFailedIndexes field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the MaxFailedIndexes field is set to the value of the last call.
func (b *JobSpecApplyConfiguration) WithMaxFailedIndexes(value int32) *JobSpecApplyConfiguration {
b.MaxFailedIndexes = &value
return b
}
// WithSelector sets the Selector field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Selector field is set to the value of the last call.
@@ -152,11 +133,3 @@ func (b *JobSpecApplyConfiguration) WithSuspend(value bool) *JobSpecApplyConfigu
b.Suspend = &value
return b
}
// WithPodReplacementPolicy sets the PodReplacementPolicy field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the PodReplacementPolicy field is set to the value of the last call.
func (b *JobSpecApplyConfiguration) WithPodReplacementPolicy(value batchv1.PodReplacementPolicy) *JobSpecApplyConfiguration {
b.PodReplacementPolicy = &value
return b
}

View File

@@ -31,9 +31,7 @@ type JobStatusApplyConfiguration struct {
Active *int32 `json:"active,omitempty"`
Succeeded *int32 `json:"succeeded,omitempty"`
Failed *int32 `json:"failed,omitempty"`
Terminating *int32 `json:"terminating,omitempty"`
CompletedIndexes *string `json:"completedIndexes,omitempty"`
FailedIndexes *string `json:"failedIndexes,omitempty"`
UncountedTerminatedPods *UncountedTerminatedPodsApplyConfiguration `json:"uncountedTerminatedPods,omitempty"`
Ready *int32 `json:"ready,omitempty"`
}
@@ -97,14 +95,6 @@ func (b *JobStatusApplyConfiguration) WithFailed(value int32) *JobStatusApplyCon
return b
}
// WithTerminating sets the Terminating field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Terminating field is set to the value of the last call.
func (b *JobStatusApplyConfiguration) WithTerminating(value int32) *JobStatusApplyConfiguration {
b.Terminating = &value
return b
}
// WithCompletedIndexes sets the CompletedIndexes field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the CompletedIndexes field is set to the value of the last call.
@@ -113,14 +103,6 @@ func (b *JobStatusApplyConfiguration) WithCompletedIndexes(value string) *JobSta
return b
}
// WithFailedIndexes sets the FailedIndexes field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the FailedIndexes field is set to the value of the last call.
func (b *JobStatusApplyConfiguration) WithFailedIndexes(value string) *JobStatusApplyConfiguration {
b.FailedIndexes = &value
return b
}
// WithUncountedTerminatedPods sets the UncountedTerminatedPods field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UncountedTerminatedPods field is set to the value of the last call.

View File

@@ -35,7 +35,6 @@ type ContainerApplyConfiguration struct {
Env []EnvVarApplyConfiguration `json:"env,omitempty"`
Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"`
ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"`
RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"`
VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"`
VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"`
LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"`
@@ -161,14 +160,6 @@ func (b *ContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResiz
return b
}
// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the RestartPolicy field is set to the value of the last call.
func (b *ContainerApplyConfiguration) WithRestartPolicy(value corev1.ContainerRestartPolicy) *ContainerApplyConfiguration {
b.RestartPolicy = &value
return b
}
// WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the VolumeMounts field.

View File

@@ -139,14 +139,6 @@ func (b *EphemeralContainerApplyConfiguration) WithResizePolicy(values ...*Conta
return b
}
// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the RestartPolicy field is set to the value of the last call.
func (b *EphemeralContainerApplyConfiguration) WithRestartPolicy(value corev1.ContainerRestartPolicy) *EphemeralContainerApplyConfiguration {
b.RestartPolicy = &value
return b
}
// WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the VolumeMounts field.

View File

@@ -35,7 +35,6 @@ type EphemeralContainerCommonApplyConfiguration struct {
Env []EnvVarApplyConfiguration `json:"env,omitempty"`
Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"`
ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"`
RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"`
VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"`
VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"`
LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"`
@@ -161,14 +160,6 @@ func (b *EphemeralContainerCommonApplyConfiguration) WithResizePolicy(values ...
return b
}
// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the RestartPolicy field is set to the value of the last call.
func (b *EphemeralContainerCommonApplyConfiguration) WithRestartPolicy(value corev1.ContainerRestartPolicy) *EphemeralContainerCommonApplyConfiguration {
b.RestartPolicy = &value
return b
}
// WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the VolumeMounts field.

View File

@@ -1,39 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1
// HostIPApplyConfiguration represents an declarative configuration of the HostIP type for use
// with apply.
type HostIPApplyConfiguration struct {
IP *string `json:"ip,omitempty"`
}
// HostIPApplyConfiguration constructs an declarative configuration of the HostIP type for use with
// apply.
func HostIP() *HostIPApplyConfiguration {
return &HostIPApplyConfiguration{}
}
// WithIP sets the IP field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the IP field is set to the value of the last call.
func (b *HostIPApplyConfiguration) WithIP(value string) *HostIPApplyConfiguration {
b.IP = &value
return b
}

View File

@@ -18,16 +18,11 @@ limitations under the License.
package v1
import (
v1 "k8s.io/api/core/v1"
)
// LoadBalancerIngressApplyConfiguration represents an declarative configuration of the LoadBalancerIngress type for use
// with apply.
type LoadBalancerIngressApplyConfiguration struct {
IP *string `json:"ip,omitempty"`
Hostname *string `json:"hostname,omitempty"`
IPMode *v1.LoadBalancerIPMode `json:"ipMode,omitempty"`
Ports []PortStatusApplyConfiguration `json:"ports,omitempty"`
}
@@ -53,14 +48,6 @@ func (b *LoadBalancerIngressApplyConfiguration) WithHostname(value string) *Load
return b
}
// WithIPMode sets the IPMode field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the IPMode field is set to the value of the last call.
func (b *LoadBalancerIngressApplyConfiguration) WithIPMode(value v1.LoadBalancerIPMode) *LoadBalancerIngressApplyConfiguration {
b.IPMode = &value
return b
}
// WithPorts adds the given value to the Ports field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Ports field.

View File

@@ -25,12 +25,12 @@ import (
// PersistentVolumeClaimStatusApplyConfiguration represents an declarative configuration of the PersistentVolumeClaimStatus type for use
// with apply.
type PersistentVolumeClaimStatusApplyConfiguration struct {
Phase *v1.PersistentVolumeClaimPhase `json:"phase,omitempty"`
AccessModes []v1.PersistentVolumeAccessMode `json:"accessModes,omitempty"`
Capacity *v1.ResourceList `json:"capacity,omitempty"`
Conditions []PersistentVolumeClaimConditionApplyConfiguration `json:"conditions,omitempty"`
AllocatedResources *v1.ResourceList `json:"allocatedResources,omitempty"`
AllocatedResourceStatuses map[v1.ResourceName]v1.ClaimResourceStatus `json:"allocatedResourceStatuses,omitempty"`
Phase *v1.PersistentVolumeClaimPhase `json:"phase,omitempty"`
AccessModes []v1.PersistentVolumeAccessMode `json:"accessModes,omitempty"`
Capacity *v1.ResourceList `json:"capacity,omitempty"`
Conditions []PersistentVolumeClaimConditionApplyConfiguration `json:"conditions,omitempty"`
AllocatedResources *v1.ResourceList `json:"allocatedResources,omitempty"`
ResizeStatus *v1.PersistentVolumeClaimResizeStatus `json:"resizeStatus,omitempty"`
}
// PersistentVolumeClaimStatusApplyConfiguration constructs an declarative configuration of the PersistentVolumeClaimStatus type for use with
@@ -86,16 +86,10 @@ func (b *PersistentVolumeClaimStatusApplyConfiguration) WithAllocatedResources(v
return b
}
// WithAllocatedResourceStatuses puts the entries into the AllocatedResourceStatuses field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, the entries provided by each call will be put on the AllocatedResourceStatuses field,
// overwriting an existing map entries in AllocatedResourceStatuses field with the same key.
func (b *PersistentVolumeClaimStatusApplyConfiguration) WithAllocatedResourceStatuses(entries map[v1.ResourceName]v1.ClaimResourceStatus) *PersistentVolumeClaimStatusApplyConfiguration {
if b.AllocatedResourceStatuses == nil && len(entries) > 0 {
b.AllocatedResourceStatuses = make(map[v1.ResourceName]v1.ClaimResourceStatus, len(entries))
}
for k, v := range entries {
b.AllocatedResourceStatuses[k] = v
}
// WithResizeStatus sets the ResizeStatus field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ResizeStatus field is set to the value of the last call.
func (b *PersistentVolumeClaimStatusApplyConfiguration) WithResizeStatus(value v1.PersistentVolumeClaimResizeStatus) *PersistentVolumeClaimStatusApplyConfiguration {
b.ResizeStatus = &value
return b
}

View File

@@ -1,48 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1
// PodResourceClaimStatusApplyConfiguration represents an declarative configuration of the PodResourceClaimStatus type for use
// with apply.
type PodResourceClaimStatusApplyConfiguration struct {
Name *string `json:"name,omitempty"`
ResourceClaimName *string `json:"resourceClaimName,omitempty"`
}
// PodResourceClaimStatusApplyConfiguration constructs an declarative configuration of the PodResourceClaimStatus type for use with
// apply.
func PodResourceClaimStatus() *PodResourceClaimStatusApplyConfiguration {
return &PodResourceClaimStatusApplyConfiguration{}
}
// WithName sets the Name field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Name field is set to the value of the last call.
func (b *PodResourceClaimStatusApplyConfiguration) WithName(value string) *PodResourceClaimStatusApplyConfiguration {
b.Name = &value
return b
}
// WithResourceClaimName sets the ResourceClaimName field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ResourceClaimName field is set to the value of the last call.
func (b *PodResourceClaimStatusApplyConfiguration) WithResourceClaimName(value string) *PodResourceClaimStatusApplyConfiguration {
b.ResourceClaimName = &value
return b
}

View File

@@ -26,22 +26,20 @@ import (
// PodStatusApplyConfiguration represents an declarative configuration of the PodStatus type for use
// with apply.
type PodStatusApplyConfiguration struct {
Phase *v1.PodPhase `json:"phase,omitempty"`
Conditions []PodConditionApplyConfiguration `json:"conditions,omitempty"`
Message *string `json:"message,omitempty"`
Reason *string `json:"reason,omitempty"`
NominatedNodeName *string `json:"nominatedNodeName,omitempty"`
HostIP *string `json:"hostIP,omitempty"`
HostIPs []HostIPApplyConfiguration `json:"hostIPs,omitempty"`
PodIP *string `json:"podIP,omitempty"`
PodIPs []PodIPApplyConfiguration `json:"podIPs,omitempty"`
StartTime *metav1.Time `json:"startTime,omitempty"`
InitContainerStatuses []ContainerStatusApplyConfiguration `json:"initContainerStatuses,omitempty"`
ContainerStatuses []ContainerStatusApplyConfiguration `json:"containerStatuses,omitempty"`
QOSClass *v1.PodQOSClass `json:"qosClass,omitempty"`
EphemeralContainerStatuses []ContainerStatusApplyConfiguration `json:"ephemeralContainerStatuses,omitempty"`
Resize *v1.PodResizeStatus `json:"resize,omitempty"`
ResourceClaimStatuses []PodResourceClaimStatusApplyConfiguration `json:"resourceClaimStatuses,omitempty"`
Phase *v1.PodPhase `json:"phase,omitempty"`
Conditions []PodConditionApplyConfiguration `json:"conditions,omitempty"`
Message *string `json:"message,omitempty"`
Reason *string `json:"reason,omitempty"`
NominatedNodeName *string `json:"nominatedNodeName,omitempty"`
HostIP *string `json:"hostIP,omitempty"`
PodIP *string `json:"podIP,omitempty"`
PodIPs []PodIPApplyConfiguration `json:"podIPs,omitempty"`
StartTime *metav1.Time `json:"startTime,omitempty"`
InitContainerStatuses []ContainerStatusApplyConfiguration `json:"initContainerStatuses,omitempty"`
ContainerStatuses []ContainerStatusApplyConfiguration `json:"containerStatuses,omitempty"`
QOSClass *v1.PodQOSClass `json:"qosClass,omitempty"`
EphemeralContainerStatuses []ContainerStatusApplyConfiguration `json:"ephemeralContainerStatuses,omitempty"`
Resize *v1.PodResizeStatus `json:"resize,omitempty"`
}
// PodStatusApplyConfiguration constructs an declarative configuration of the PodStatus type for use with
@@ -103,19 +101,6 @@ func (b *PodStatusApplyConfiguration) WithHostIP(value string) *PodStatusApplyCo
return b
}
// WithHostIPs adds the given value to the HostIPs field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the HostIPs field.
func (b *PodStatusApplyConfiguration) WithHostIPs(values ...*HostIPApplyConfiguration) *PodStatusApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithHostIPs")
}
b.HostIPs = append(b.HostIPs, *values[i])
}
return b
}
// WithPodIP sets the PodIP field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the PodIP field is set to the value of the last call.
@@ -199,16 +184,3 @@ func (b *PodStatusApplyConfiguration) WithResize(value v1.PodResizeStatus) *PodS
b.Resize = &value
return b
}
// WithResourceClaimStatuses adds the given value to the ResourceClaimStatuses field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the ResourceClaimStatuses field.
func (b *PodStatusApplyConfiguration) WithResourceClaimStatuses(values ...*PodResourceClaimStatusApplyConfiguration) *PodStatusApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithResourceClaimStatuses")
}
b.ResourceClaimStatuses = append(b.ResourceClaimStatuses, *values[i])
}
return b
}

View File

@@ -32,7 +32,8 @@ import (
type NetworkPolicyApplyConfiguration struct {
v1.TypeMetaApplyConfiguration `json:",inline"`
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
Spec *NetworkPolicySpecApplyConfiguration `json:"spec,omitempty"`
Spec *NetworkPolicySpecApplyConfiguration `json:"spec,omitempty"`
Status *NetworkPolicyStatusApplyConfiguration `json:"status,omitempty"`
}
// NetworkPolicy constructs an declarative configuration of the NetworkPolicy type for use with
@@ -247,3 +248,11 @@ func (b *NetworkPolicyApplyConfiguration) WithSpec(value *NetworkPolicySpecApply
b.Spec = value
return b
}
// WithStatus sets the Status field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Status field is set to the value of the last call.
func (b *NetworkPolicyApplyConfiguration) WithStatus(value *NetworkPolicyStatusApplyConfiguration) *NetworkPolicyApplyConfiguration {
b.Status = value
return b
}

View File

@@ -0,0 +1,48 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1beta1
import (
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
)
// NetworkPolicyStatusApplyConfiguration represents an declarative configuration of the NetworkPolicyStatus type for use
// with apply.
type NetworkPolicyStatusApplyConfiguration struct {
Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
}
// NetworkPolicyStatusApplyConfiguration constructs an declarative configuration of the NetworkPolicyStatus type for use with
// apply.
func NetworkPolicyStatus() *NetworkPolicyStatusApplyConfiguration {
return &NetworkPolicyStatusApplyConfiguration{}
}
// WithConditions adds the given value to the Conditions field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Conditions field.
func (b *NetworkPolicyStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *NetworkPolicyStatusApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithConditions")
}
b.Conditions = append(b.Conditions, *values[i])
}
return b
}

View File

@@ -1,48 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1alpha1
// ExemptPriorityLevelConfigurationApplyConfiguration represents an declarative configuration of the ExemptPriorityLevelConfiguration type for use
// with apply.
type ExemptPriorityLevelConfigurationApplyConfiguration struct {
NominalConcurrencyShares *int32 `json:"nominalConcurrencyShares,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
}
// ExemptPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the ExemptPriorityLevelConfiguration type for use with
// apply.
func ExemptPriorityLevelConfiguration() *ExemptPriorityLevelConfigurationApplyConfiguration {
return &ExemptPriorityLevelConfigurationApplyConfiguration{}
}
// WithNominalConcurrencyShares sets the NominalConcurrencyShares field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the NominalConcurrencyShares field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithNominalConcurrencyShares(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.NominalConcurrencyShares = &value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}

View File

@@ -27,7 +27,6 @@ import (
type PriorityLevelConfigurationSpecApplyConfiguration struct {
Type *v1alpha1.PriorityLevelEnablement `json:"type,omitempty"`
Limited *LimitedPriorityLevelConfigurationApplyConfiguration `json:"limited,omitempty"`
Exempt *ExemptPriorityLevelConfigurationApplyConfiguration `json:"exempt,omitempty"`
}
// PriorityLevelConfigurationSpecApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationSpec type for use with
@@ -51,11 +50,3 @@ func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithLimited(value *Li
b.Limited = value
return b
}
// WithExempt sets the Exempt field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Exempt field is set to the value of the last call.
func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithExempt(value *ExemptPriorityLevelConfigurationApplyConfiguration) *PriorityLevelConfigurationSpecApplyConfiguration {
b.Exempt = value
return b
}

View File

@@ -1,48 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1beta1
// ExemptPriorityLevelConfigurationApplyConfiguration represents an declarative configuration of the ExemptPriorityLevelConfiguration type for use
// with apply.
type ExemptPriorityLevelConfigurationApplyConfiguration struct {
NominalConcurrencyShares *int32 `json:"nominalConcurrencyShares,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
}
// ExemptPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the ExemptPriorityLevelConfiguration type for use with
// apply.
func ExemptPriorityLevelConfiguration() *ExemptPriorityLevelConfigurationApplyConfiguration {
return &ExemptPriorityLevelConfigurationApplyConfiguration{}
}
// WithNominalConcurrencyShares sets the NominalConcurrencyShares field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the NominalConcurrencyShares field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithNominalConcurrencyShares(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.NominalConcurrencyShares = &value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}

View File

@@ -27,7 +27,6 @@ import (
type PriorityLevelConfigurationSpecApplyConfiguration struct {
Type *v1beta1.PriorityLevelEnablement `json:"type,omitempty"`
Limited *LimitedPriorityLevelConfigurationApplyConfiguration `json:"limited,omitempty"`
Exempt *ExemptPriorityLevelConfigurationApplyConfiguration `json:"exempt,omitempty"`
}
// PriorityLevelConfigurationSpecApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationSpec type for use with
@@ -51,11 +50,3 @@ func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithLimited(value *Li
b.Limited = value
return b
}
// WithExempt sets the Exempt field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Exempt field is set to the value of the last call.
func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithExempt(value *ExemptPriorityLevelConfigurationApplyConfiguration) *PriorityLevelConfigurationSpecApplyConfiguration {
b.Exempt = value
return b
}

View File

@@ -1,48 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1beta2
// ExemptPriorityLevelConfigurationApplyConfiguration represents an declarative configuration of the ExemptPriorityLevelConfiguration type for use
// with apply.
type ExemptPriorityLevelConfigurationApplyConfiguration struct {
NominalConcurrencyShares *int32 `json:"nominalConcurrencyShares,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
}
// ExemptPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the ExemptPriorityLevelConfiguration type for use with
// apply.
func ExemptPriorityLevelConfiguration() *ExemptPriorityLevelConfigurationApplyConfiguration {
return &ExemptPriorityLevelConfigurationApplyConfiguration{}
}
// WithNominalConcurrencyShares sets the NominalConcurrencyShares field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the NominalConcurrencyShares field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithNominalConcurrencyShares(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.NominalConcurrencyShares = &value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}

View File

@@ -27,7 +27,6 @@ import (
type PriorityLevelConfigurationSpecApplyConfiguration struct {
Type *v1beta2.PriorityLevelEnablement `json:"type,omitempty"`
Limited *LimitedPriorityLevelConfigurationApplyConfiguration `json:"limited,omitempty"`
Exempt *ExemptPriorityLevelConfigurationApplyConfiguration `json:"exempt,omitempty"`
}
// PriorityLevelConfigurationSpecApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationSpec type for use with
@@ -51,11 +50,3 @@ func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithLimited(value *Li
b.Limited = value
return b
}
// WithExempt sets the Exempt field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Exempt field is set to the value of the last call.
func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithExempt(value *ExemptPriorityLevelConfigurationApplyConfiguration) *PriorityLevelConfigurationSpecApplyConfiguration {
b.Exempt = value
return b
}

View File

@@ -1,48 +0,0 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1beta3
// ExemptPriorityLevelConfigurationApplyConfiguration represents an declarative configuration of the ExemptPriorityLevelConfiguration type for use
// with apply.
type ExemptPriorityLevelConfigurationApplyConfiguration struct {
NominalConcurrencyShares *int32 `json:"nominalConcurrencyShares,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
}
// ExemptPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the ExemptPriorityLevelConfiguration type for use with
// apply.
func ExemptPriorityLevelConfiguration() *ExemptPriorityLevelConfigurationApplyConfiguration {
return &ExemptPriorityLevelConfigurationApplyConfiguration{}
}
// WithNominalConcurrencyShares sets the NominalConcurrencyShares field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the NominalConcurrencyShares field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithNominalConcurrencyShares(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.NominalConcurrencyShares = &value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *ExemptPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *ExemptPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}

View File

@@ -27,7 +27,6 @@ import (
type PriorityLevelConfigurationSpecApplyConfiguration struct {
Type *v1beta3.PriorityLevelEnablement `json:"type,omitempty"`
Limited *LimitedPriorityLevelConfigurationApplyConfiguration `json:"limited,omitempty"`
Exempt *ExemptPriorityLevelConfigurationApplyConfiguration `json:"exempt,omitempty"`
}
// PriorityLevelConfigurationSpecApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationSpec type for use with
@@ -51,11 +50,3 @@ func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithLimited(value *Li
b.Limited = value
return b
}
// WithExempt sets the Exempt field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Exempt field is set to the value of the last call.
func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithExempt(value *ExemptPriorityLevelConfigurationApplyConfiguration) *PriorityLevelConfigurationSpecApplyConfiguration {
b.Exempt = value
return b
}

View File

@@ -366,12 +366,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: namespace
type:
scalar: string
- name: parameterNotFoundAction
type:
scalar: string
- name: selector
type:
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector
elementRelationship: atomic
- name: io.k8s.api.admissionregistration.v1alpha1.TypeChecking
map:
@@ -470,14 +464,6 @@ var schemaYAML = typed.YAMLObject(`types:
elementType:
namedType: io.k8s.api.admissionregistration.v1alpha1.Validation
elementRelationship: atomic
- name: variables
type:
list:
elementType:
namedType: io.k8s.api.admissionregistration.v1alpha1.Variable
elementRelationship: associative
keys:
- name
- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus
map:
fields:
@@ -511,17 +497,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: reason
type:
scalar: string
- name: io.k8s.api.admissionregistration.v1alpha1.Variable
map:
fields:
- name: expression
type:
scalar: string
default: ""
- name: name
type:
scalar: string
default: ""
- name: io.k8s.api.admissionregistration.v1beta1.MatchCondition
map:
fields:
@@ -720,12 +695,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: encodingVersion
type:
scalar: string
- name: servedVersions
type:
list:
elementType:
scalar: string
elementRelationship: associative
- name: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion
map:
fields:
@@ -3359,9 +3328,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: backoffLimit
type:
scalar: numeric
- name: backoffLimitPerIndex
type:
scalar: numeric
- name: completionMode
type:
scalar: string
@@ -3371,18 +3337,12 @@ var schemaYAML = typed.YAMLObject(`types:
- name: manualSelector
type:
scalar: boolean
- name: maxFailedIndexes
type:
scalar: numeric
- name: parallelism
type:
scalar: numeric
- name: podFailurePolicy
type:
namedType: io.k8s.api.batch.v1.PodFailurePolicy
- name: podReplacementPolicy
type:
scalar: string
- name: selector
type:
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector
@@ -3417,9 +3377,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: failed
type:
scalar: numeric
- name: failedIndexes
type:
scalar: string
- name: ready
type:
scalar: numeric
@@ -3429,9 +3386,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: succeeded
type:
scalar: numeric
- name: terminating
type:
scalar: numeric
- name: uncountedTerminatedPods
type:
namedType: io.k8s.api.batch.v1.UncountedTerminatedPods
@@ -4352,9 +4306,6 @@ var schemaYAML = typed.YAMLObject(`types:
type:
namedType: io.k8s.api.core.v1.ResourceRequirements
default: {}
- name: restartPolicy
type:
scalar: string
- name: securityContext
type:
namedType: io.k8s.api.core.v1.SecurityContext
@@ -4772,9 +4723,6 @@ var schemaYAML = typed.YAMLObject(`types:
type:
namedType: io.k8s.api.core.v1.ResourceRequirements
default: {}
- name: restartPolicy
type:
scalar: string
- name: securityContext
type:
namedType: io.k8s.api.core.v1.SecurityContext
@@ -5105,12 +5053,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: ip
type:
scalar: string
- name: io.k8s.api.core.v1.HostIP
map:
fields:
- name: ip
type:
scalar: string
- name: io.k8s.api.core.v1.HostPathVolumeSource
map:
fields:
@@ -5307,9 +5249,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: ip
type:
scalar: string
- name: ipMode
type:
scalar: string
- name: ports
type:
list:
@@ -5838,12 +5777,6 @@ var schemaYAML = typed.YAMLObject(`types:
elementType:
scalar: string
elementRelationship: atomic
- name: allocatedResourceStatuses
type:
map:
elementType:
scalar: string
elementRelationship: separable
- name: allocatedResources
type:
map:
@@ -5865,6 +5798,9 @@ var schemaYAML = typed.YAMLObject(`types:
- name: phase
type:
scalar: string
- name: resizeStatus
type:
scalar: string
- name: io.k8s.api.core.v1.PersistentVolumeClaimTemplate
map:
fields:
@@ -6166,16 +6102,6 @@ var schemaYAML = typed.YAMLObject(`types:
type:
namedType: io.k8s.api.core.v1.ClaimSource
default: {}
- name: io.k8s.api.core.v1.PodResourceClaimStatus
map:
fields:
- name: name
type:
scalar: string
default: ""
- name: resourceClaimName
type:
scalar: string
- name: io.k8s.api.core.v1.PodSchedulingGate
map:
fields:
@@ -6425,12 +6351,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: hostIP
type:
scalar: string
- name: hostIPs
type:
list:
elementType:
namedType: io.k8s.api.core.v1.HostIP
elementRelationship: atomic
- name: initContainerStatuses
type:
list:
@@ -6466,14 +6386,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: resize
type:
scalar: string
- name: resourceClaimStatuses
type:
list:
elementType:
namedType: io.k8s.api.core.v1.PodResourceClaimStatus
elementRelationship: associative
keys:
- name
- name: startTime
type:
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time
@@ -8431,6 +8343,10 @@ var schemaYAML = typed.YAMLObject(`types:
type:
namedType: io.k8s.api.extensions.v1beta1.NetworkPolicySpec
default: {}
- name: status
type:
namedType: io.k8s.api.extensions.v1beta1.NetworkPolicyStatus
default: {}
- name: io.k8s.api.extensions.v1beta1.NetworkPolicyEgressRule
map:
fields:
@@ -8510,6 +8426,17 @@ var schemaYAML = typed.YAMLObject(`types:
elementType:
scalar: string
elementRelationship: atomic
- name: io.k8s.api.extensions.v1beta1.NetworkPolicyStatus
map:
fields:
- name: conditions
type:
list:
elementType:
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition
elementRelationship: associative
keys:
- type
- name: io.k8s.api.extensions.v1beta1.ReplicaSet
map:
fields:
@@ -8619,15 +8546,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: maxUnavailable
type:
namedType: io.k8s.apimachinery.pkg.util.intstr.IntOrString
- name: io.k8s.api.flowcontrol.v1alpha1.ExemptPriorityLevelConfiguration
map:
fields:
- name: lendablePercent
type:
scalar: numeric
- name: nominalConcurrencyShares
type:
scalar: numeric
- name: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod
map:
fields:
@@ -8831,9 +8749,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationSpec
map:
fields:
- name: exempt
type:
namedType: io.k8s.api.flowcontrol.v1alpha1.ExemptPriorityLevelConfiguration
- name: limited
type:
namedType: io.k8s.api.flowcontrol.v1alpha1.LimitedPriorityLevelConfiguration
@@ -8844,8 +8759,6 @@ var schemaYAML = typed.YAMLObject(`types:
unions:
- discriminator: type
fields:
- fieldName: exempt
discriminatorValue: Exempt
- fieldName: limited
discriminatorValue: Limited
- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationStatus
@@ -8947,15 +8860,6 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: string
default: ""
- name: io.k8s.api.flowcontrol.v1beta1.ExemptPriorityLevelConfiguration
map:
fields:
- name: lendablePercent
type:
scalar: numeric
- name: nominalConcurrencyShares
type:
scalar: numeric
- name: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod
map:
fields:
@@ -9159,9 +9063,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec
map:
fields:
- name: exempt
type:
namedType: io.k8s.api.flowcontrol.v1beta1.ExemptPriorityLevelConfiguration
- name: limited
type:
namedType: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration
@@ -9172,8 +9073,6 @@ var schemaYAML = typed.YAMLObject(`types:
unions:
- discriminator: type
fields:
- fieldName: exempt
discriminatorValue: Exempt
- fieldName: limited
discriminatorValue: Limited
- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationStatus
@@ -9275,15 +9174,6 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: string
default: ""
- name: io.k8s.api.flowcontrol.v1beta2.ExemptPriorityLevelConfiguration
map:
fields:
- name: lendablePercent
type:
scalar: numeric
- name: nominalConcurrencyShares
type:
scalar: numeric
- name: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod
map:
fields:
@@ -9487,9 +9377,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec
map:
fields:
- name: exempt
type:
namedType: io.k8s.api.flowcontrol.v1beta2.ExemptPriorityLevelConfiguration
- name: limited
type:
namedType: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration
@@ -9500,8 +9387,6 @@ var schemaYAML = typed.YAMLObject(`types:
unions:
- discriminator: type
fields:
- fieldName: exempt
discriminatorValue: Exempt
- fieldName: limited
discriminatorValue: Limited
- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationStatus
@@ -9603,15 +9488,6 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: string
default: ""
- name: io.k8s.api.flowcontrol.v1beta3.ExemptPriorityLevelConfiguration
map:
fields:
- name: lendablePercent
type:
scalar: numeric
- name: nominalConcurrencyShares
type:
scalar: numeric
- name: io.k8s.api.flowcontrol.v1beta3.FlowDistinguisherMethod
map:
fields:
@@ -9815,9 +9691,6 @@ var schemaYAML = typed.YAMLObject(`types:
- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationSpec
map:
fields:
- name: exempt
type:
namedType: io.k8s.api.flowcontrol.v1beta3.ExemptPriorityLevelConfiguration
- name: limited
type:
namedType: io.k8s.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration
@@ -9828,8 +9701,6 @@ var schemaYAML = typed.YAMLObject(`types:
unions:
- discriminator: type
fields:
- fieldName: exempt
discriminatorValue: Exempt
- fieldName: limited
discriminatorValue: Limited
- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationStatus
@@ -10216,6 +10087,10 @@ var schemaYAML = typed.YAMLObject(`types:
type:
namedType: io.k8s.api.networking.v1.NetworkPolicySpec
default: {}
- name: status
type:
namedType: io.k8s.api.networking.v1.NetworkPolicyStatus
default: {}
- name: io.k8s.api.networking.v1.NetworkPolicyEgressRule
map:
fields:
@@ -10295,6 +10170,17 @@ var schemaYAML = typed.YAMLObject(`types:
elementType:
scalar: string
elementRelationship: atomic
- name: io.k8s.api.networking.v1.NetworkPolicyStatus
map:
fields:
- name: conditions
type:
list:
elementType:
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition
elementRelationship: associative
keys:
- type
- name: io.k8s.api.networking.v1.ServiceBackendPort
map:
fields:

View File

@@ -32,7 +32,8 @@ import (
type NetworkPolicyApplyConfiguration struct {
v1.TypeMetaApplyConfiguration `json:",inline"`
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
Spec *NetworkPolicySpecApplyConfiguration `json:"spec,omitempty"`
Spec *NetworkPolicySpecApplyConfiguration `json:"spec,omitempty"`
Status *NetworkPolicyStatusApplyConfiguration `json:"status,omitempty"`
}
// NetworkPolicy constructs an declarative configuration of the NetworkPolicy type for use with
@@ -247,3 +248,11 @@ func (b *NetworkPolicyApplyConfiguration) WithSpec(value *NetworkPolicySpecApply
b.Spec = value
return b
}
// WithStatus sets the Status field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Status field is set to the value of the last call.
func (b *NetworkPolicyApplyConfiguration) WithStatus(value *NetworkPolicyStatusApplyConfiguration) *NetworkPolicyApplyConfiguration {
b.Status = value
return b
}

View File

@@ -0,0 +1,48 @@
/*
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 applyconfiguration-gen. DO NOT EDIT.
package v1
import (
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
)
// NetworkPolicyStatusApplyConfiguration represents an declarative configuration of the NetworkPolicyStatus type for use
// with apply.
type NetworkPolicyStatusApplyConfiguration struct {
Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
}
// NetworkPolicyStatusApplyConfiguration constructs an declarative configuration of the NetworkPolicyStatus type for use with
// apply.
func NetworkPolicyStatus() *NetworkPolicyStatusApplyConfiguration {
return &NetworkPolicyStatusApplyConfiguration{}
}
// WithConditions adds the given value to the Conditions field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Conditions field.
func (b *NetworkPolicyStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *NetworkPolicyStatusApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithConditions")
}
b.Conditions = append(b.Conditions, *values[i])
}
return b
}

View File

@@ -171,8 +171,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &admissionregistrationv1alpha1.ValidatingAdmissionPolicyStatusApplyConfiguration{}
case v1alpha1.SchemeGroupVersion.WithKind("Validation"):
return &admissionregistrationv1alpha1.ValidationApplyConfiguration{}
case v1alpha1.SchemeGroupVersion.WithKind("Variable"):
return &admissionregistrationv1alpha1.VariableApplyConfiguration{}
// Group=admissionregistration.k8s.io, Version=v1beta1
case v1beta1.SchemeGroupVersion.WithKind("MatchCondition"):
@@ -677,8 +675,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationscorev1.GRPCActionApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("HostAlias"):
return &applyconfigurationscorev1.HostAliasApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("HostIP"):
return &applyconfigurationscorev1.HostIPApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("HostPathVolumeSource"):
return &applyconfigurationscorev1.HostPathVolumeSourceApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("HTTPGetAction"):
@@ -793,8 +789,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationscorev1.PodReadinessGateApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("PodResourceClaim"):
return &applyconfigurationscorev1.PodResourceClaimApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("PodResourceClaimStatus"):
return &applyconfigurationscorev1.PodResourceClaimStatusApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("PodSchedulingGate"):
return &applyconfigurationscorev1.PodSchedulingGateApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("PodSecurityContext"):
@@ -1025,6 +1019,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationsextensionsv1beta1.NetworkPolicyPortApplyConfiguration{}
case extensionsv1beta1.SchemeGroupVersion.WithKind("NetworkPolicySpec"):
return &applyconfigurationsextensionsv1beta1.NetworkPolicySpecApplyConfiguration{}
case extensionsv1beta1.SchemeGroupVersion.WithKind("NetworkPolicyStatus"):
return &applyconfigurationsextensionsv1beta1.NetworkPolicyStatusApplyConfiguration{}
case extensionsv1beta1.SchemeGroupVersion.WithKind("ReplicaSet"):
return &applyconfigurationsextensionsv1beta1.ReplicaSetApplyConfiguration{}
case extensionsv1beta1.SchemeGroupVersion.WithKind("ReplicaSetCondition"):
@@ -1043,8 +1039,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationsextensionsv1beta1.ScaleApplyConfiguration{}
// Group=flowcontrol.apiserver.k8s.io, Version=v1alpha1
case flowcontrolv1alpha1.SchemeGroupVersion.WithKind("ExemptPriorityLevelConfiguration"):
return &applyconfigurationsflowcontrolv1alpha1.ExemptPriorityLevelConfigurationApplyConfiguration{}
case flowcontrolv1alpha1.SchemeGroupVersion.WithKind("FlowDistinguisherMethod"):
return &applyconfigurationsflowcontrolv1alpha1.FlowDistinguisherMethodApplyConfiguration{}
case flowcontrolv1alpha1.SchemeGroupVersion.WithKind("FlowSchema"):
@@ -1087,8 +1081,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationsflowcontrolv1alpha1.UserSubjectApplyConfiguration{}
// Group=flowcontrol.apiserver.k8s.io, Version=v1beta1
case flowcontrolv1beta1.SchemeGroupVersion.WithKind("ExemptPriorityLevelConfiguration"):
return &applyconfigurationsflowcontrolv1beta1.ExemptPriorityLevelConfigurationApplyConfiguration{}
case flowcontrolv1beta1.SchemeGroupVersion.WithKind("FlowDistinguisherMethod"):
return &applyconfigurationsflowcontrolv1beta1.FlowDistinguisherMethodApplyConfiguration{}
case flowcontrolv1beta1.SchemeGroupVersion.WithKind("FlowSchema"):
@@ -1131,8 +1123,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationsflowcontrolv1beta1.UserSubjectApplyConfiguration{}
// Group=flowcontrol.apiserver.k8s.io, Version=v1beta2
case flowcontrolv1beta2.SchemeGroupVersion.WithKind("ExemptPriorityLevelConfiguration"):
return &applyconfigurationsflowcontrolv1beta2.ExemptPriorityLevelConfigurationApplyConfiguration{}
case flowcontrolv1beta2.SchemeGroupVersion.WithKind("FlowDistinguisherMethod"):
return &applyconfigurationsflowcontrolv1beta2.FlowDistinguisherMethodApplyConfiguration{}
case flowcontrolv1beta2.SchemeGroupVersion.WithKind("FlowSchema"):
@@ -1175,8 +1165,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationsflowcontrolv1beta2.UserSubjectApplyConfiguration{}
// Group=flowcontrol.apiserver.k8s.io, Version=v1beta3
case v1beta3.SchemeGroupVersion.WithKind("ExemptPriorityLevelConfiguration"):
return &flowcontrolv1beta3.ExemptPriorityLevelConfigurationApplyConfiguration{}
case v1beta3.SchemeGroupVersion.WithKind("FlowDistinguisherMethod"):
return &flowcontrolv1beta3.FlowDistinguisherMethodApplyConfiguration{}
case v1beta3.SchemeGroupVersion.WithKind("FlowSchema"):
@@ -1305,6 +1293,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationsnetworkingv1.NetworkPolicyPortApplyConfiguration{}
case networkingv1.SchemeGroupVersion.WithKind("NetworkPolicySpec"):
return &applyconfigurationsnetworkingv1.NetworkPolicySpecApplyConfiguration{}
case networkingv1.SchemeGroupVersion.WithKind("NetworkPolicyStatus"):
return &applyconfigurationsnetworkingv1.NetworkPolicyStatusApplyConfiguration{}
case networkingv1.SchemeGroupVersion.WithKind("ServiceBackendPort"):
return &applyconfigurationsnetworkingv1.ServiceBackendPortApplyConfiguration{}

View File

@@ -25,7 +25,7 @@ import (
"sync"
"time"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
"k8s.io/klog/v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -26,7 +26,7 @@ import (
"testing"
"time"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

View File

@@ -22,7 +22,7 @@ import (
"sync"
"syscall"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
errorsutil "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -30,7 +30,7 @@ import (
//nolint:staticcheck // SA1019 Keep using module since it's still being maintained and the api of google.golang.org/protobuf/proto differs
"github.com/golang/protobuf/proto"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
apidiscovery "k8s.io/api/apidiscovery/v2beta1"
"k8s.io/apimachinery/pkg/api/errors"

View File

@@ -26,8 +26,8 @@ import (
"time"
"github.com/gogo/protobuf/proto"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v3 "github.com/google/gnostic-models/openapiv3"
openapi_v2 "github.com/google/gnostic/openapiv2"
openapi_v3 "github.com/google/gnostic/openapiv3"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -36,6 +36,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/openapi"
@@ -436,7 +437,7 @@ func TestGetServerResourcesForGroupVersion(t *testing.T) {
"extensions/v1beta10",
}
if !reflect.DeepEqual(expectedGroupVersions, serverGroupVersions) {
t.Errorf("unexpected group versions: %v", cmp.Diff(expectedGroupVersions, serverGroupVersions))
t.Errorf("unexpected group versions: %v", diff.ObjectReflectDiff(expectedGroupVersions, serverGroupVersions))
}
}

View File

@@ -20,7 +20,7 @@ import (
"fmt"
"net/http"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -21,12 +21,12 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/dynamic/fake"
"k8s.io/client-go/tools/cache"
@@ -118,7 +118,7 @@ func TestFilteredDynamicSharedInformerFactory(t *testing.T) {
t.Errorf("informer received an object for namespace %s when watching namespace %s", ts.ns, ts.informNS)
}
if !equality.Semantic.DeepEqual(testObject, objFromInformer) {
t.Fatalf("%v", cmp.Diff(testObject, objFromInformer))
t.Fatalf("%v", diff.ObjectDiff(testObject, objFromInformer))
}
case <-ctx.Done():
if ts.ns == ts.informNS {
@@ -239,7 +239,7 @@ func TestDynamicSharedInformerFactory(t *testing.T) {
select {
case objFromInformer := <-informerReciveObjectCh:
if !equality.Semantic.DeepEqual(testObject, objFromInformer) {
t.Fatalf("%v", cmp.Diff(testObject, objFromInformer))
t.Fatalf("%v", diff.ObjectDiff(testObject, objFromInformer))
}
case <-ctx.Done():
t.Errorf("tested informer haven't received an object, waited %v", timeout)

View File

@@ -20,11 +20,11 @@ import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/dynamic/dynamiclister"
"k8s.io/client-go/tools/cache"
)
@@ -90,7 +90,7 @@ func TestNamespaceGetMethod(t *testing.T) {
t.Fatal(err)
}
if !reflect.DeepEqual(test.expectedObject, actualObject) {
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject))
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject))
}
})
}
@@ -188,7 +188,7 @@ func TestListerGetMethod(t *testing.T) {
t.Fatal(err)
}
if !reflect.DeepEqual(test.expectedObject, actualObject) {
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject))
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject))
}
})
}
@@ -245,7 +245,7 @@ func assertListOrDie(expected, actual []*unstructured.Unstructured, t *testing.T
for _, actualObject := range actual {
if actualObject.GetName() == expectedObject.GetName() {
if !reflect.DeepEqual(expectedObject, actualObject) {
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, cmp.Diff(expectedObject, actualObject))
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, diff.ObjectDiff(expectedObject, actualObject))
}
found = true
}

View File

@@ -28,6 +28,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/diff"
)
const (
@@ -79,7 +80,7 @@ func TestGet(t *testing.T) {
},
}
if !equality.Semantic.DeepEqual(get, expected) {
t.Fatal(cmp.Diff(expected, get))
t.Fatal(diff.ObjectGoPrintDiff(expected, get))
}
}
@@ -98,7 +99,7 @@ func TestListDecoding(t *testing.T) {
Items: []unstructured.Unstructured{},
}
if !equality.Semantic.DeepEqual(list, expectedList) {
t.Fatal(cmp.Diff(expectedList, list))
t.Fatal(diff.ObjectGoPrintDiff(expectedList, list))
}
}
@@ -116,7 +117,7 @@ func TestGetDecoding(t *testing.T) {
},
}
if !equality.Semantic.DeepEqual(get, expectedObj) {
t.Fatal(cmp.Diff(expectedObj, get))
t.Fatal(diff.ObjectGoPrintDiff(expectedObj, get))
}
}
@@ -144,7 +145,7 @@ func TestList(t *testing.T) {
*newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
}
if !equality.Semantic.DeepEqual(listFirst.Items, expected) {
t.Fatal(cmp.Diff(expected, listFirst.Items))
t.Fatal(diff.ObjectGoPrintDiff(expected, listFirst.Items))
}
}
@@ -188,7 +189,7 @@ func Test_ListKind(t *testing.T) {
},
}
if !equality.Semantic.DeepEqual(listFirst, expectedList) {
t.Fatal(cmp.Diff(expectedList, listFirst))
t.Fatal(diff.ObjectGoPrintDiff(expectedList, listFirst))
}
}
@@ -241,7 +242,7 @@ func (tc *patchTestCase) verifyResult(result *unstructured.Unstructured) error {
return nil
}
if !equality.Semantic.DeepEqual(result, tc.expectedPatchedObject) {
return fmt.Errorf("unexpected diff in received object: %s", cmp.Diff(tc.expectedPatchedObject, result))
return fmt.Errorf("unexpected diff in received object: %s", diff.ObjectGoPrintDiff(tc.expectedPatchedObject, result))
}
return nil
}

43
go.mod
View File

@@ -5,40 +5,40 @@ module k8s.io/client-go
go 1.20
require (
github.com/evanphx/json-patch v5.6.0+incompatible
github.com/davecgh/go-spew v1.1.1
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/gogo/protobuf v1.3.2
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
github.com/golang/protobuf v1.5.3
github.com/google/gnostic-models v0.6.8
github.com/google/gnostic v0.5.7-v3refs
github.com/google/go-cmp v0.5.9
github.com/google/gofuzz v1.2.0
github.com/google/gofuzz v1.1.0
github.com/google/uuid v1.3.0
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7
github.com/imdario/mergo v0.3.6
github.com/peterbourgon/diskv v2.0.1+incompatible
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.2
golang.org/x/net v0.12.0
golang.org/x/oauth2 v0.8.0
golang.org/x/term v0.10.0
golang.org/x/time v0.3.0
google.golang.org/protobuf v1.30.0
k8s.io/api v0.28.0-beta.0
k8s.io/apimachinery v0.28.0-beta.0
k8s.io/klog/v2 v2.100.1
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
github.com/stretchr/testify v1.8.1
golang.org/x/net v0.8.0
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
golang.org/x/term v0.6.0
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
google.golang.org/protobuf v1.28.1
k8s.io/api v0.27.2
k8s.io/apimachinery v0.27.2
k8s.io/klog/v2 v2.90.1
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f
k8s.io/utils v0.0.0-20230209194617-a36077c30491
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd
sigs.k8s.io/structured-merge-diff/v4 v4.2.3
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.1 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
@@ -48,11 +48,10 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/gomega v1.27.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
@@ -60,6 +59,6 @@ require (
)
replace (
k8s.io/api => k8s.io/api v0.28.0-beta.0
k8s.io/apimachinery => k8s.io/apimachinery v0.28.0-beta.0
k8s.io/api => k8s.io/api v0.27.2
k8s.io/apimachinery => k8s.io/apimachinery v0.27.2
)

418
go.sum
View File

@@ -1,56 +1,157 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -66,96 +167,329 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.28.0-beta.0 h1:RQib3xI/dxXb2TPvSVRLvAjBjOMnU7jD0GwIAbKwBqU=
k8s.io/api v0.28.0-beta.0/go.mod h1:AF3hqmc5wvnZD2G4klXcRB9jBn8XEkr+2KvFbpwbvnw=
k8s.io/apimachinery v0.28.0-beta.0 h1:n3ksD30Isi22awAww6cnQVC8JhnID1Ow4Jhi7ylEHNY=
k8s.io/apimachinery v0.28.0-beta.0/go.mod h1:xhQIsaL3hXneGluH+0pzF7kr+VYuLS/VcYJxF1xQf+g=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo=
k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4=
k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg=
k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=

View File

@@ -184,7 +184,7 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref
return res
}
// InformerFor returns the SharedIndexInformer for obj using an internal
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
// client.
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
@@ -257,7 +257,7 @@ type SharedInformerFactory interface {
// ForResource gives generic access to a shared informer of the matching type.
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
// InformerFor returns the SharedIndexInformer for obj using an internal
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
// client.
InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer

View File

@@ -28,7 +28,6 @@ import (
type AuthenticationV1Interface interface {
RESTClient() rest.Interface
SelfSubjectReviewsGetter
TokenReviewsGetter
}
@@ -37,10 +36,6 @@ type AuthenticationV1Client struct {
restClient rest.Interface
}
func (c *AuthenticationV1Client) SelfSubjectReviews() SelfSubjectReviewInterface {
return newSelfSubjectReviews(c)
}
func (c *AuthenticationV1Client) TokenReviews() TokenReviewInterface {
return newTokenReviews(c)
}

View File

@@ -28,10 +28,6 @@ type FakeAuthenticationV1 struct {
*testing.Fake
}
func (c *FakeAuthenticationV1) SelfSubjectReviews() v1.SelfSubjectReviewInterface {
return &FakeSelfSubjectReviews{c}
}
func (c *FakeAuthenticationV1) TokenReviews() v1.TokenReviewInterface {
return &FakeTokenReviews{c}
}

View File

@@ -1,46 +0,0 @@
/*
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 client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/api/authentication/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
testing "k8s.io/client-go/testing"
)
// FakeSelfSubjectReviews implements SelfSubjectReviewInterface
type FakeSelfSubjectReviews struct {
Fake *FakeAuthenticationV1
}
var selfsubjectreviewsResource = v1.SchemeGroupVersion.WithResource("selfsubjectreviews")
var selfsubjectreviewsKind = v1.SchemeGroupVersion.WithKind("SelfSubjectReview")
// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any.
func (c *FakeSelfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1.SelfSubjectReview, opts metav1.CreateOptions) (result *v1.SelfSubjectReview, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(selfsubjectreviewsResource, selfSubjectReview), &v1.SelfSubjectReview{})
if obj == nil {
return nil, err
}
return obj.(*v1.SelfSubjectReview), err
}

View File

@@ -18,6 +18,4 @@ limitations under the License.
package v1
type SelfSubjectReviewExpansion interface{}
type TokenReviewExpansion interface{}

View File

@@ -1,64 +0,0 @@
/*
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 client-gen. DO NOT EDIT.
package v1
import (
"context"
v1 "k8s.io/api/authentication/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
scheme "k8s.io/client-go/kubernetes/scheme"
rest "k8s.io/client-go/rest"
)
// SelfSubjectReviewsGetter has a method to return a SelfSubjectReviewInterface.
// A group's client should implement this interface.
type SelfSubjectReviewsGetter interface {
SelfSubjectReviews() SelfSubjectReviewInterface
}
// SelfSubjectReviewInterface has methods to work with SelfSubjectReview resources.
type SelfSubjectReviewInterface interface {
Create(ctx context.Context, selfSubjectReview *v1.SelfSubjectReview, opts metav1.CreateOptions) (*v1.SelfSubjectReview, error)
SelfSubjectReviewExpansion
}
// selfSubjectReviews implements SelfSubjectReviewInterface
type selfSubjectReviews struct {
client rest.Interface
}
// newSelfSubjectReviews returns a SelfSubjectReviews
func newSelfSubjectReviews(c *AuthenticationV1Client) *selfSubjectReviews {
return &selfSubjectReviews{
client: c.RESTClient(),
}
}
// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any.
func (c *selfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1.SelfSubjectReview, opts metav1.CreateOptions) (result *v1.SelfSubjectReview, err error) {
result = &v1.SelfSubjectReview{}
err = c.client.Post().
Resource("selfsubjectreviews").
VersionedParams(&opts, scheme.ParameterCodec).
Body(selfSubjectReview).
Do(ctx).
Into(result)
return
}

View File

@@ -104,6 +104,18 @@ func (c *FakeNetworkPolicies) Update(ctx context.Context, networkPolicy *v1beta1
return obj.(*v1beta1.NetworkPolicy), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeNetworkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1beta1.NetworkPolicy, opts v1.UpdateOptions) (*v1beta1.NetworkPolicy, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(networkpoliciesResource, "status", c.ns, networkPolicy), &v1beta1.NetworkPolicy{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.NetworkPolicy), err
}
// Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs.
func (c *FakeNetworkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
@@ -152,3 +164,26 @@ func (c *FakeNetworkPolicies) Apply(ctx context.Context, networkPolicy *extensio
}
return obj.(*v1beta1.NetworkPolicy), err
}
// ApplyStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
func (c *FakeNetworkPolicies) ApplyStatus(ctx context.Context, networkPolicy *extensionsv1beta1.NetworkPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.NetworkPolicy, err error) {
if networkPolicy == nil {
return nil, fmt.Errorf("networkPolicy provided to Apply must not be nil")
}
data, err := json.Marshal(networkPolicy)
if err != nil {
return nil, err
}
name := networkPolicy.Name
if name == nil {
return nil, fmt.Errorf("networkPolicy.Name must be provided to Apply")
}
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1beta1.NetworkPolicy{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.NetworkPolicy), err
}

View File

@@ -43,6 +43,7 @@ type NetworkPoliciesGetter interface {
type NetworkPolicyInterface interface {
Create(ctx context.Context, networkPolicy *v1beta1.NetworkPolicy, opts v1.CreateOptions) (*v1beta1.NetworkPolicy, error)
Update(ctx context.Context, networkPolicy *v1beta1.NetworkPolicy, opts v1.UpdateOptions) (*v1beta1.NetworkPolicy, error)
UpdateStatus(ctx context.Context, networkPolicy *v1beta1.NetworkPolicy, opts v1.UpdateOptions) (*v1beta1.NetworkPolicy, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.NetworkPolicy, error)
@@ -50,6 +51,7 @@ type NetworkPolicyInterface interface {
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.NetworkPolicy, err error)
Apply(ctx context.Context, networkPolicy *extensionsv1beta1.NetworkPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.NetworkPolicy, err error)
ApplyStatus(ctx context.Context, networkPolicy *extensionsv1beta1.NetworkPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.NetworkPolicy, err error)
NetworkPolicyExpansion
}
@@ -139,6 +141,22 @@ func (c *networkPolicies) Update(ctx context.Context, networkPolicy *v1beta1.Net
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *networkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1beta1.NetworkPolicy, opts v1.UpdateOptions) (result *v1beta1.NetworkPolicy, err error) {
result = &v1beta1.NetworkPolicy{}
err = c.client.Put().
Namespace(c.ns).
Resource("networkpolicies").
Name(networkPolicy.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(networkPolicy).
Do(ctx).
Into(result)
return
}
// Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs.
func (c *networkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
@@ -206,3 +224,33 @@ func (c *networkPolicies) Apply(ctx context.Context, networkPolicy *extensionsv1
Into(result)
return
}
// ApplyStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
func (c *networkPolicies) ApplyStatus(ctx context.Context, networkPolicy *extensionsv1beta1.NetworkPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.NetworkPolicy, err error) {
if networkPolicy == nil {
return nil, fmt.Errorf("networkPolicy provided to Apply must not be nil")
}
patchOpts := opts.ToPatchOptions()
data, err := json.Marshal(networkPolicy)
if err != nil {
return nil, err
}
name := networkPolicy.Name
if name == nil {
return nil, fmt.Errorf("networkPolicy.Name must be provided to Apply")
}
result = &v1beta1.NetworkPolicy{}
err = c.client.Patch(types.ApplyPatchType).
Namespace(c.ns).
Resource("networkpolicies").
Name(*name).
SubResource("status").
VersionedParams(&patchOpts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -104,6 +104,18 @@ func (c *FakeNetworkPolicies) Update(ctx context.Context, networkPolicy *v1.Netw
return obj.(*v1.NetworkPolicy), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeNetworkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.UpdateOptions) (*v1.NetworkPolicy, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(networkpoliciesResource, "status", c.ns, networkPolicy), &v1.NetworkPolicy{})
if obj == nil {
return nil, err
}
return obj.(*v1.NetworkPolicy), err
}
// Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs.
func (c *FakeNetworkPolicies) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
_, err := c.Fake.
@@ -152,3 +164,26 @@ func (c *FakeNetworkPolicies) Apply(ctx context.Context, networkPolicy *networki
}
return obj.(*v1.NetworkPolicy), err
}
// ApplyStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
func (c *FakeNetworkPolicies) ApplyStatus(ctx context.Context, networkPolicy *networkingv1.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *v1.NetworkPolicy, err error) {
if networkPolicy == nil {
return nil, fmt.Errorf("networkPolicy provided to Apply must not be nil")
}
data, err := json.Marshal(networkPolicy)
if err != nil {
return nil, err
}
name := networkPolicy.Name
if name == nil {
return nil, fmt.Errorf("networkPolicy.Name must be provided to Apply")
}
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.NetworkPolicy{})
if obj == nil {
return nil, err
}
return obj.(*v1.NetworkPolicy), err
}

View File

@@ -43,6 +43,7 @@ type NetworkPoliciesGetter interface {
type NetworkPolicyInterface interface {
Create(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.CreateOptions) (*v1.NetworkPolicy, error)
Update(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.UpdateOptions) (*v1.NetworkPolicy, error)
UpdateStatus(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.UpdateOptions) (*v1.NetworkPolicy, error)
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error)
@@ -50,6 +51,7 @@ type NetworkPolicyInterface interface {
Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.NetworkPolicy, err error)
Apply(ctx context.Context, networkPolicy *networkingv1.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *v1.NetworkPolicy, err error)
ApplyStatus(ctx context.Context, networkPolicy *networkingv1.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *v1.NetworkPolicy, err error)
NetworkPolicyExpansion
}
@@ -139,6 +141,22 @@ func (c *networkPolicies) Update(ctx context.Context, networkPolicy *v1.NetworkP
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *networkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.UpdateOptions) (result *v1.NetworkPolicy, err error) {
result = &v1.NetworkPolicy{}
err = c.client.Put().
Namespace(c.ns).
Resource("networkpolicies").
Name(networkPolicy.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(networkPolicy).
Do(ctx).
Into(result)
return
}
// Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs.
func (c *networkPolicies) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
return c.client.Delete().
@@ -206,3 +224,33 @@ func (c *networkPolicies) Apply(ctx context.Context, networkPolicy *networkingv1
Into(result)
return
}
// ApplyStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
func (c *networkPolicies) ApplyStatus(ctx context.Context, networkPolicy *networkingv1.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *v1.NetworkPolicy, err error) {
if networkPolicy == nil {
return nil, fmt.Errorf("networkPolicy provided to Apply must not be nil")
}
patchOpts := opts.ToPatchOptions()
data, err := json.Marshal(networkPolicy)
if err != nil {
return nil, err
}
name := networkPolicy.Name
if name == nil {
return nil, fmt.Errorf("networkPolicy.Name must be provided to Apply")
}
result = &v1.NetworkPolicy{}
err = c.client.Patch(types.ApplyPatchType).
Namespace(c.ns).
Resource("networkpolicies").
Name(*name).
SubResource("status").
VersionedParams(&patchOpts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -23,9 +23,10 @@ import (
"net/http"
"testing"
"github.com/davecgh/go-spew/spew"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
@@ -38,7 +39,7 @@ func TestListTimeout(t *testing.T) {
NegotiatedSerializer: scheme.Codecs,
Client: manualfake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Query().Get("timeout") != "21s" {
t.Fatal(dump.Pretty(req.URL.Query()))
t.Fatal(spew.Sdump(req.URL.Query()))
}
return &http.Response{StatusCode: http.StatusNotFound, Body: io.NopCloser(&bytes.Buffer{})}, nil
}),

View File

@@ -21,12 +21,12 @@ import (
"fmt"
"testing"
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/diff"
)
const (
@@ -79,7 +79,7 @@ func TestList(t *testing.T) {
*newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"),
}
if !equality.Semantic.DeepEqual(listFirst.Items, expected) {
t.Fatal(cmp.Diff(expected, listFirst.Items))
t.Fatal(diff.ObjectGoPrintDiff(expected, listFirst.Items))
}
}
@@ -134,7 +134,7 @@ func (tc *patchTestCase) verifyResult(result *metav1.PartialObjectMetadata) erro
return nil
}
if !equality.Semantic.DeepEqual(result, tc.expectedPatchedObject) {
return fmt.Errorf("unexpected diff in received object: %s", cmp.Diff(tc.expectedPatchedObject, result))
return fmt.Errorf("unexpected diff in received object: %s", diff.ObjectGoPrintDiff(tc.expectedPatchedObject, result))
}
return nil
}

View File

@@ -26,11 +26,11 @@ import (
"strings"
"testing"
"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/rest"
)
@@ -89,7 +89,7 @@ func TestClient(t *testing.T) {
},
}
if !reflect.DeepEqual(expect, obj) {
t.Fatal(cmp.Diff(expect, obj))
t.Fatal(diff.ObjectReflectDiff(expect, obj))
}
},
},
@@ -146,7 +146,7 @@ func TestClient(t *testing.T) {
},
}
if !reflect.DeepEqual(expect, objs.Items) {
t.Fatal(cmp.Diff(expect, objs.Items))
t.Fatal(diff.ObjectReflectDiff(expect, objs.Items))
}
},
},

View File

@@ -22,13 +22,13 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"k8s.io/klog/v2"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/metadata/fake"
"k8s.io/client-go/tools/cache"
)
@@ -147,7 +147,7 @@ func TestMetadataSharedInformerFactory(t *testing.T) {
select {
case objFromInformer := <-informerReciveObjectCh:
if !equality.Semantic.DeepEqual(testObject, objFromInformer) {
t.Fatalf("%v", cmp.Diff(testObject, objFromInformer))
t.Fatalf("%v", diff.ObjectDiff(testObject, objFromInformer))
}
case <-ctx.Done():
t.Errorf("tested informer haven't received an object, waited %v", timeout)

View File

@@ -20,11 +20,11 @@ import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/tools/cache"
)
@@ -89,7 +89,7 @@ func TestNamespaceGetMethod(t *testing.T) {
t.Fatal(err)
}
if !reflect.DeepEqual(test.expectedObject, actualObject) {
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject))
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject))
}
})
}
@@ -187,7 +187,7 @@ func TestListerGetMethod(t *testing.T) {
t.Fatal(err)
}
if !reflect.DeepEqual(test.expectedObject, actualObject) {
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject))
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject))
}
})
}
@@ -231,7 +231,7 @@ func assertListOrDie(expected, actual []*metav1.PartialObjectMetadata, t *testin
for _, actualObject := range actual {
if actualObject.GetName() == expectedObject.GetName() {
if !reflect.DeepEqual(expectedObject, actualObject) {
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, cmp.Diff(expectedObject, actualObject))
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, diff.ObjectDiff(expectedObject, actualObject))
}
found = true
}

View File

@@ -19,35 +19,33 @@ package openapitest
import (
"embed"
"errors"
"io/fs"
"os"
"path/filepath"
"strings"
"sync"
"testing"
"k8s.io/client-go/openapi"
)
//go:embed testdata/*_openapi.json
var embedded embed.FS
var f embed.FS
// NewFileClient returns a test client implementing the openapi.Client
// interface, which serves Open API V3 specifications files from the
// given path, as prepared in `api/openapi-spec/v3`.
func NewFileClient(path string) openapi.Client {
return &fileClient{f: os.DirFS(path)}
}
// NewEmbeddedFileClient returns a test client that uses the embedded
// `testdata` openapi files.
func NewEmbeddedFileClient() openapi.Client {
f, err := fs.Sub(embedded, "testdata")
if err != nil {
panic(err)
// interface, which serves a subset of hard-coded GroupVersion
// Open API V3 specifications files. The subset of specifications is
// located in the "testdata" subdirectory.
func NewFileClient(t *testing.T) openapi.Client {
if t == nil {
panic("non-nil testing.T required; this package is only for use in tests")
}
return &fileClient{f: f}
return &fileClient{t: t}
}
type fileClient struct {
f fs.FS
t *testing.T
init sync.Once
paths map[string]openapi.GroupVersion
err error
}
// fileClient implements the openapi.Client interface.
@@ -62,23 +60,29 @@ var _ openapi.Client = &fileClient{}
//
// The file contents are read only once. All files must parse correctly
// into an api path, or an error is returned.
func (f *fileClient) Paths() (map[string]openapi.GroupVersion, error) {
paths := map[string]openapi.GroupVersion{}
entries, err := fs.ReadDir(f.f, ".")
if err != nil {
return nil, err
}
for _, e := range entries {
// this reverses the transformation done in hack/update-openapi-spec.sh
path := strings.ReplaceAll(strings.TrimSuffix(e.Name(), "_openapi.json"), "__", "/")
paths[path] = &fileGroupVersion{f: f.f, filename: e.Name()}
}
return paths, nil
func (t *fileClient) Paths() (map[string]openapi.GroupVersion, error) {
t.init.Do(func() {
t.paths = map[string]openapi.GroupVersion{}
entries, err := f.ReadDir("testdata")
if err != nil {
t.err = err
t.t.Error(err)
}
for _, e := range entries {
// this reverses the transformation done in hack/update-openapi-spec.sh
path := strings.ReplaceAll(strings.TrimSuffix(e.Name(), "_openapi.json"), "__", "/")
t.paths[path] = &fileGroupVersion{t: t.t, filename: filepath.Join("testdata", e.Name())}
}
})
return t.paths, t.err
}
type fileGroupVersion struct {
f fs.FS
t *testing.T
init sync.Once
filename string
data []byte
err error
}
// fileGroupVersion implements the openapi.GroupVersion interface.
@@ -87,10 +91,17 @@ var _ openapi.GroupVersion = &fileGroupVersion{}
// Schema returns the OpenAPI V3 specification for the GroupVersion as
// unstructured bytes, or an error if the contentType is not
// "application/json" or there is an error reading the spec file. The
// file is read only once.
func (f *fileGroupVersion) Schema(contentType string) ([]byte, error) {
// file is read only once. The embedded file is located in the "testdata"
// subdirectory.
func (t *fileGroupVersion) Schema(contentType string) ([]byte, error) {
if contentType != "application/json" {
return nil, errors.New("openapitest only supports 'application/json' contentType")
}
return fs.ReadFile(f.f, f.filename)
t.init.Do(func() {
t.data, t.err = f.ReadFile(t.filename)
if t.err != nil {
t.t.Error(t.err)
}
})
return t.data, t.err
}

View File

@@ -14,61 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package openapitest_test
package openapitest
import (
"testing"
"k8s.io/client-go/openapi/openapitest"
"k8s.io/kube-openapi/pkg/spec3"
kjson "sigs.k8s.io/json"
"testing"
)
func TestOpenAPIEmbeddedTest(t *testing.T) {
client := openapitest.NewEmbeddedFileClient()
// make sure we get paths
paths, err := client.Paths()
if err != nil {
t.Fatalf("error fetching paths: %v", err)
}
if len(paths) == 0 {
t.Error("empty paths")
}
// spot check specific paths
expectedPaths := []string{
"api/v1",
"apis/apps/v1",
"apis/batch/v1",
"apis/networking.k8s.io/v1alpha1",
"apis/discovery.k8s.io/v1",
}
for _, p := range expectedPaths {
if _, ok := paths[p]; !ok {
t.Fatalf("expected %s", p)
}
}
// make sure all paths can load
for path, gv := range paths {
data, err := gv.Schema("application/json")
if err != nil {
t.Fatalf("error reading schema for %v: %v", path, err)
}
o := &spec3.OpenAPI{}
stricterrs, err := kjson.UnmarshalStrict(data, o)
if err != nil {
t.Fatalf("error unmarshaling schema for %v: %v", path, err)
}
if len(stricterrs) > 0 {
t.Fatalf("strict errors unmarshaling schema for %v: %v", path, stricterrs)
}
}
}
func TestOpenAPITest(t *testing.T) {
client := openapitest.NewFileClient("testdata")
client := NewFileClient(t)
// make sure we get paths
paths, err := client.Paths()

View File

@@ -1,48 +0,0 @@
/*
Copyright 2023 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 openapi
import (
"encoding/json"
"fmt"
"k8s.io/apimachinery/pkg/util/managedfields"
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/validation/spec"
)
func NewTypeConverter(client Client, preserveUnknownFields bool) (managedfields.TypeConverter, error) {
spec := map[string]*spec.Schema{}
paths, err := client.Paths()
if err != nil {
return nil, fmt.Errorf("failed to list paths: %w", err)
}
for _, gv := range paths {
s, err := gv.Schema("application/json")
if err != nil {
return nil, fmt.Errorf("failed to download schema: %w", err)
}
var openapi spec3.OpenAPI
if err := json.Unmarshal(s, &openapi); err != nil {
return nil, fmt.Errorf("failed to parse schema: %w", err)
}
for k, v := range openapi.Components.Schemas {
spec[k] = v
}
}
return managedfields.NewTypeConverter(spec, preserveUnknownFields)
}

View File

@@ -150,7 +150,7 @@ func TestOpenAPIV3Root_GVSpec(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
client := openapitest.NewEmbeddedFileClient()
client := openapitest.NewFileClient(t)
root := NewRoot(client)
gvSpec, err := root.GVSpec(test.gv)
if test.err != nil {
@@ -209,7 +209,8 @@ func TestOpenAPIV3Root_GVSpecAsMap(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
root := NewRoot(openapitest.NewEmbeddedFileClient())
client := openapitest.NewFileClient(t)
root := NewRoot(client)
gvSpecAsMap, err := root.GVSpecAsMap(test.gv)
if test.err != nil {
assert.True(t, reflect.DeepEqual(test.err, err))

View File

@@ -32,12 +32,12 @@ import (
"sync"
"time"
"github.com/davecgh/go-spew/spew"
"golang.org/x/term"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/dump"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/client-go/pkg/apis/clientauthentication"
"k8s.io/client-go/pkg/apis/clientauthentication/install"
@@ -81,6 +81,8 @@ func newCache() *cache {
return &cache{m: make(map[string]*Authenticator)}
}
var spewConfig = &spew.ConfigState{DisableMethods: true, Indent: " "}
func cacheKey(conf *api.ExecConfig, cluster *clientauthentication.Cluster) string {
key := struct {
conf *api.ExecConfig
@@ -89,7 +91,7 @@ func cacheKey(conf *api.ExecConfig, cluster *clientauthentication.Cluster) strin
conf: conf,
cluster: cluster,
}
return dump.Pretty(key)
return spewConfig.Sprint(key)
}
type cache struct {

View File

@@ -23,6 +23,7 @@ import (
"net/http/httptest"
"net/http/httputil"
"net/url"
"os"
"reflect"
"testing"
"time"
@@ -339,8 +340,8 @@ func TestCreateBackoffManager(t *testing.T) {
theUrl, _ := url.Parse("http://localhost")
// 1 second base backoff + duration of 2 seconds -> exponential backoff for requests.
t.Setenv(envBackoffBase, "1")
t.Setenv(envBackoffDuration, "2")
os.Setenv(envBackoffBase, "1")
os.Setenv(envBackoffDuration, "2")
backoff := readExpBackoffConfig()
backoff.UpdateBackoff(theUrl, nil, 500)
backoff.UpdateBackoff(theUrl, nil, 500)
@@ -349,8 +350,8 @@ func TestCreateBackoffManager(t *testing.T) {
}
// 0 duration -> no backoff.
t.Setenv(envBackoffBase, "1")
t.Setenv(envBackoffDuration, "0")
os.Setenv(envBackoffBase, "1")
os.Setenv(envBackoffDuration, "0")
backoff.UpdateBackoff(theUrl, nil, 500)
backoff.UpdateBackoff(theUrl, nil, 500)
backoff = readExpBackoffConfig()
@@ -359,8 +360,8 @@ func TestCreateBackoffManager(t *testing.T) {
}
// No env -> No backoff.
t.Setenv(envBackoffBase, "")
t.Setenv(envBackoffDuration, "")
os.Setenv(envBackoffBase, "")
os.Setenv(envBackoffDuration, "")
backoff = readExpBackoffConfig()
backoff.UpdateBackoff(theUrl, nil, 500)
backoff.UpdateBackoff(theUrl, nil, 500)

View File

@@ -316,7 +316,7 @@ func RESTClientFor(config *Config) (*RESTClient, error) {
// Validate config.Host before constructing the transport/client so we can fail fast.
// ServerURL will be obtained later in RESTClientForConfigAndClient()
_, _, err := DefaultServerUrlFor(config)
_, _, err := defaultServerUrlFor(config)
if err != nil {
return nil, err
}
@@ -343,7 +343,7 @@ func RESTClientForConfigAndClient(config *Config, httpClient *http.Client) (*RES
return nil, fmt.Errorf("NegotiatedSerializer is required when initializing a RESTClient")
}
baseURL, versionedAPIPath, err := DefaultServerUrlFor(config)
baseURL, versionedAPIPath, err := defaultServerUrlFor(config)
if err != nil {
return nil, err
}
@@ -390,7 +390,7 @@ func UnversionedRESTClientFor(config *Config) (*RESTClient, error) {
// Validate config.Host before constructing the transport/client so we can fail fast.
// ServerURL will be obtained later in UnversionedRESTClientForConfigAndClient()
_, _, err := DefaultServerUrlFor(config)
_, _, err := defaultServerUrlFor(config)
if err != nil {
return nil, err
}
@@ -410,7 +410,7 @@ func UnversionedRESTClientForConfigAndClient(config *Config, httpClient *http.Cl
return nil, fmt.Errorf("NegotiatedSerializer is required when initializing a RESTClient")
}
baseURL, versionedAPIPath, err := DefaultServerUrlFor(config)
baseURL, versionedAPIPath, err := defaultServerUrlFor(config)
if err != nil {
return nil, err
}
@@ -548,7 +548,7 @@ func InClusterConfig() (*Config, error) {
// Note: the Insecure flag is ignored when testing for this value, so MITM attacks are
// still possible.
func IsConfigTransportTLS(config Config) bool {
baseURL, _, err := DefaultServerUrlFor(&config)
baseURL, _, err := defaultServerUrlFor(&config)
if err != nil {
return false
}

View File

@@ -24,6 +24,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"strconv"
"strings"
"sync/atomic"
@@ -79,15 +80,23 @@ func newLB(t *testing.T, serverURL string) *tcpLB {
return &lb
}
func setEnv(key, value string) func() {
originalValue := os.Getenv(key)
os.Setenv(key, value)
return func() {
os.Setenv(key, originalValue)
}
}
const (
readIdleTimeout int = 1
pingTimeout int = 1
)
func TestReconnectBrokenTCP(t *testing.T) {
t.Setenv("HTTP2_READ_IDLE_TIMEOUT_SECONDS", strconv.Itoa(readIdleTimeout))
t.Setenv("HTTP2_PING_TIMEOUT_SECONDS", strconv.Itoa(pingTimeout))
t.Setenv("DISABLE_HTTP2", "")
defer setEnv("HTTP2_READ_IDLE_TIMEOUT_SECONDS", strconv.Itoa(readIdleTimeout))()
defer setEnv("HTTP2_PING_TIMEOUT_SECONDS", strconv.Itoa(pingTimeout))()
defer setEnv("DISABLE_HTTP2", "")()
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s", r.Proto)
}))

View File

@@ -24,7 +24,6 @@ import (
"io"
"mime"
"net/http"
"net/http/httptrace"
"net/url"
"os"
"path"
@@ -926,38 +925,15 @@ func (r *Request) newHTTPRequest(ctx context.Context) (*http.Request, error) {
}
url := r.URL().String()
req, err := http.NewRequestWithContext(httptrace.WithClientTrace(ctx, newDNSMetricsTrace(ctx)), r.verb, url, body)
req, err := http.NewRequest(r.verb, url, body)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
req.Header = r.headers
return req, nil
}
// newDNSMetricsTrace returns an HTTP trace that tracks time spent on DNS lookups per host.
// This metric is available in client as "rest_client_dns_resolution_duration_seconds".
func newDNSMetricsTrace(ctx context.Context) *httptrace.ClientTrace {
type dnsMetric struct {
start time.Time
host string
sync.Mutex
}
dns := &dnsMetric{}
return &httptrace.ClientTrace{
DNSStart: func(info httptrace.DNSStartInfo) {
dns.Lock()
defer dns.Unlock()
dns.start = time.Now()
dns.host = info.Host
},
DNSDone: func(info httptrace.DNSDoneInfo) {
dns.Lock()
defer dns.Unlock()
metrics.ResolverLatency.Observe(ctx, dns.host, time.Since(dns.start))
},
}
}
// request connects to the server and invokes the provided function when a server response is
// received. It handles retry behavior and up front validation of requests. It will invoke
// fn at most once. It will return an error if a problem occurred prior to connecting to the

View File

@@ -45,6 +45,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/intstr"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/watch"
@@ -139,6 +140,11 @@ func TestRequestAbsPathPreservesTrailingSlash(t *testing.T) {
if s := r.URL().String(); s != "/foo/" {
t.Errorf("trailing slash should be preserved: %s", s)
}
r = (&Request{c: &RESTClient{base: &url.URL{}}}).AbsPath("/foo/")
if s := r.URL().String(); s != "/foo/" {
t.Errorf("trailing slash should be preserved: %s", s)
}
}
func TestRequestAbsPathJoins(t *testing.T) {
@@ -317,7 +323,7 @@ func TestRequestBody(t *testing.T) {
}
// test error set when failing to read file
f, err := os.CreateTemp("", "")
f, err := os.CreateTemp("", "test")
if err != nil {
t.Fatalf("unable to create temp file")
}
@@ -919,22 +925,22 @@ func TestTransformUnstructuredError(t *testing.T) {
expect = err
}
if !reflect.DeepEqual(expect, transformed) {
t.Errorf("unexpected Error(): %s", cmp.Diff(expect, transformed))
t.Errorf("unexpected Error(): %s", diff.ObjectReflectDiff(expect, transformed))
}
// verify result.Get properly transforms the error
if _, err := result.Get(); !reflect.DeepEqual(expect, err) {
t.Errorf("unexpected error on Get(): %s", cmp.Diff(expect, err))
t.Errorf("unexpected error on Get(): %s", diff.ObjectReflectDiff(expect, err))
}
// verify result.Into properly handles the error
if err := result.Into(&v1.Pod{}); !reflect.DeepEqual(expect, err) {
t.Errorf("unexpected error on Into(): %s", cmp.Diff(expect, err))
t.Errorf("unexpected error on Into(): %s", diff.ObjectReflectDiff(expect, err))
}
// verify result.Raw leaves the error in the untransformed state
if _, err := result.Raw(); !reflect.DeepEqual(result.err, err) {
t.Errorf("unexpected error on Raw(): %s", cmp.Diff(expect, err))
t.Errorf("unexpected error on Raw(): %s", diff.ObjectReflectDiff(expect, err))
}
})
}
@@ -1214,7 +1220,7 @@ func TestRequestWatch(t *testing.T) {
t.Fatalf("Watch closed early, %d/%d read", i, len(testCase.Expect))
}
if !reflect.DeepEqual(evt, out) {
t.Fatalf("Event %d does not match: %s", i, cmp.Diff(evt, out))
t.Fatalf("Event %d does not match: %s", i, diff.ObjectReflectDiff(evt, out))
}
}
}
@@ -1460,7 +1466,7 @@ func TestDoRequestNewWay(t *testing.T) {
expectedObj := &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{
Protocol: "TCP",
Port: 12345,
TargetPort: intstr.FromInt32(12345),
TargetPort: intstr.FromInt(12345),
}}}}
expectedBody, _ := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expectedObj)
fakeHandler := utiltesting.FakeHandler{
@@ -1703,7 +1709,7 @@ func TestDoRequestNewWayReader(t *testing.T) {
expectedObj := &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{
Protocol: "TCP",
Port: 12345,
TargetPort: intstr.FromInt32(12345),
TargetPort: intstr.FromInt(12345),
}}}}
expectedBody, _ := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expectedObj)
fakeHandler := utiltesting.FakeHandler{
@@ -1742,7 +1748,7 @@ func TestDoRequestNewWayObj(t *testing.T) {
expectedObj := &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{
Protocol: "TCP",
Port: 12345,
TargetPort: intstr.FromInt32(12345),
TargetPort: intstr.FromInt(12345),
}}}}
expectedBody, _ := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expectedObj)
fakeHandler := utiltesting.FakeHandler{
@@ -1797,7 +1803,7 @@ func TestDoRequestNewWayFile(t *testing.T) {
expectedObj := &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{
Protocol: "TCP",
Port: 12345,
TargetPort: intstr.FromInt32(12345),
TargetPort: intstr.FromInt(12345),
}}}}
expectedBody, _ := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expectedObj)
fakeHandler := utiltesting.FakeHandler{
@@ -1842,7 +1848,7 @@ func TestWasCreated(t *testing.T) {
expectedObj := &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{
Protocol: "TCP",
Port: 12345,
TargetPort: intstr.FromInt32(12345),
TargetPort: intstr.FromInt(12345),
}}}}
expectedBody, _ := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expectedObj)
fakeHandler := utiltesting.FakeHandler{

View File

@@ -77,9 +77,9 @@ func DefaultVersionedAPIPath(apiPath string, groupVersion schema.GroupVersion) s
return versionedAPIPath
}
// DefaultServerUrlFor is shared between IsConfigTransportTLS and RESTClientFor. It
// defaultServerUrlFor is shared between IsConfigTransportTLS and RESTClientFor. It
// requires Host and Version to be set prior to being called.
func DefaultServerUrlFor(config *Config) (*url.URL, string, error) {
func defaultServerUrlFor(config *Config) (*url.URL, string, error) {
// TODO: move the default to secure when the apiserver supports TLS by default
// config.Insecure is taken to mean "I want HTTPS but don't bother checking the certs against a CA."
hasCA := len(config.CAFile) != 0 || len(config.CAData) != 0

View File

@@ -21,17 +21,17 @@ import (
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/version"
. "k8s.io/client-go/discovery"
"k8s.io/client-go/openapi"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
"github.com/stretchr/testify/assert"
)
@@ -364,7 +364,7 @@ func TestGetAPIGroupResources(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(test.expected, got) {
t.Errorf("unexpected result:\nexpected = %s\ngot = %s", dump.Pretty(test.expected), dump.Pretty(got))
t.Errorf("unexpected result:\nexpected = %s\ngot = %s", spew.Sdump(test.expected), spew.Sdump(got))
}
})
}

View File

@@ -19,7 +19,7 @@ package restmapper
import (
"testing"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
openapi_v2 "github.com/google/gnostic/openapiv2"
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/api/errors"

4
tools/cache/OWNERS vendored
View File

@@ -2,6 +2,7 @@
approvers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
@@ -10,6 +11,7 @@ approvers:
- ncdc
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
@@ -24,5 +26,3 @@ reviewers:
- dims
- ingvagabund
- ncdc
emeritus_approvers:
- lavalamp

View File

@@ -18,6 +18,7 @@ package cache
import (
"errors"
"os"
"sync"
"time"
@@ -147,6 +148,9 @@ func (c *controller) Run(stopCh <-chan struct{}) {
if c.config.WatchErrorHandler != nil {
r.watchErrorHandler = c.config.WatchErrorHandler
}
if s := os.Getenv("ENABLE_CLIENT_GO_WATCH_LIST_ALPHA"); len(s) > 0 {
r.UseWatchList = true
}
c.reflectorMutex.Lock()
c.reflector = r

View File

@@ -1,65 +0,0 @@
/*
Copyright 2023 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 cache
import (
"k8s.io/apimachinery/pkg/types"
)
// ObjectName is a reference to an object of some implicit kind
type ObjectName struct {
Namespace string
Name string
}
// NewObjectName constructs a new one
func NewObjectName(namespace, name string) ObjectName {
return ObjectName{Namespace: namespace, Name: name}
}
// Parts is the inverse of the constructor
func (objName ObjectName) Parts() (namespace, name string) {
return objName.Namespace, objName.Name
}
// String returns the standard string encoding,
// which is designed to match the historical behavior of MetaNamespaceKeyFunc.
// Note this behavior is different from the String method of types.NamespacedName.
func (objName ObjectName) String() string {
if len(objName.Namespace) > 0 {
return objName.Namespace + "/" + objName.Name
}
return objName.Name
}
// ParseObjectName tries to parse the standard encoding
func ParseObjectName(str string) (ObjectName, error) {
var objName ObjectName
var err error
objName.Namespace, objName.Name, err = SplitMetaNamespaceKey(str)
return objName, err
}
// NamespacedNameAsObjectName rebrands the given NamespacedName as an ObjectName
func NamespacedNameAsObjectName(nn types.NamespacedName) ObjectName {
return NewObjectName(nn.Namespace, nn.Name)
}
// AsNamespacedName rebrands as a NamespacedName
func (objName ObjectName) AsNamespacedName() types.NamespacedName {
return types.NamespacedName{Namespace: objName.Namespace, Name: objName.Name}
}

View File

@@ -1,59 +0,0 @@
/*
Copyright 2023 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 cache
import (
"math/rand"
"strings"
"testing"
)
func TestObjectNames(t *testing.T) {
chars := "abcdefghi/"
for count := 1; count <= 100; count++ {
var encodedB strings.Builder
for index := 0; index < 10; index++ {
encodedB.WriteByte(chars[rand.Intn(len(chars))])
}
encodedS := encodedB.String()
parts := strings.Split(encodedS, "/")
on, err := ParseObjectName(encodedS)
expectError := len(parts) > 2
if expectError != (err != nil) {
t.Errorf("Wrong error; expected=%v, got=%v", expectError, err)
}
if expectError || err != nil {
continue
}
var expectedObjectName ObjectName
if len(parts) == 2 {
expectedObjectName = ObjectName{Namespace: parts[0], Name: parts[1]}
} else {
expectedObjectName = ObjectName{Name: encodedS}
}
if on != expectedObjectName {
t.Errorf("Parse failed, expected=%+v, got=%+v", expectedObjectName, on)
}
recoded := on.String()
if encodedS[0] == '/' {
recoded = "/" + recoded
}
if encodedS != recoded {
t.Errorf("Parse().String() was not identity, original=%q, final=%q", encodedS, recoded)
}
}
}

View File

@@ -22,7 +22,6 @@ import (
"fmt"
"io"
"math/rand"
"os"
"reflect"
"strings"
"sync"
@@ -70,7 +69,9 @@ type Reflector struct {
listerWatcher ListerWatcher
// backoff manages backoff of ListWatch
backoffManager wait.BackoffManager
resyncPeriod time.Duration
// initConnBackoffManager manages backoff the initial connection with the Watch call of ListAndWatch.
initConnBackoffManager wait.BackoffManager
resyncPeriod time.Duration
// clock allows tests to manipulate time
clock clock.Clock
// paginatedResult defines whether pagination should be forced for list calls.
@@ -219,10 +220,11 @@ func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store S
// We used to make the call every 1sec (1 QPS), the goal here is to achieve ~98% traffic reduction when
// API server is not healthy. With these parameters, backoff will stop at [30,60) sec interval which is
// 0.22 QPS. If we don't backoff for 2min, assume API server is healthy and we reset the backoff.
backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock),
clock: reflectorClock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
expectedType: reflect.TypeOf(expectedType),
backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock),
initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock),
clock: reflectorClock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
expectedType: reflect.TypeOf(expectedType),
}
if r.name == "" {
@@ -237,10 +239,6 @@ func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store S
r.expectedGVK = getExpectedGVKFromObject(expectedType)
}
if s := os.Getenv("ENABLE_CLIENT_GO_WATCH_LIST_ALPHA"); len(s) > 0 {
r.UseWatchList = true
}
return r
}
@@ -422,7 +420,7 @@ func (r *Reflector) watch(w watch.Interface, stopCh <-chan struct{}, resyncerrc
select {
case <-stopCh:
return nil
case <-r.backoffManager.Backoff().C():
case <-r.initConnBackoffManager.Backoff().C():
continue
}
}
@@ -448,7 +446,7 @@ func (r *Reflector) watch(w watch.Interface, stopCh <-chan struct{}, resyncerrc
select {
case <-stopCh:
return nil
case <-r.backoffManager.Backoff().C():
case <-r.initConnBackoffManager.Backoff().C():
continue
}
case apierrors.IsInternalError(err) && retry.ShouldRetry():
@@ -510,7 +508,7 @@ func (r *Reflector) list(stopCh <-chan struct{}) error {
pager.PageSize = 0
}
list, paginatedResult, err = pager.ListWithAlloc(context.Background(), options)
list, paginatedResult, err = pager.List(context.Background(), options)
if isExpiredError(err) || isTooLargeResourceVersionError(err) {
r.setIsLastSyncResourceVersionUnavailable(true)
// Retry immediately if the resource version used to list is unavailable.
@@ -519,7 +517,7 @@ func (r *Reflector) list(stopCh <-chan struct{}) error {
// resource version it is listing at is expired or the cache may not yet be synced to the provided
// resource version. So we need to fallback to resourceVersion="" in all to recover and ensure
// the reflector makes forward progress.
list, paginatedResult, err = pager.ListWithAlloc(context.Background(), metav1.ListOptions{ResourceVersion: r.relistResourceVersion()})
list, paginatedResult, err = pager.List(context.Background(), metav1.ListOptions{ResourceVersion: r.relistResourceVersion()})
}
close(listCh)
}()
@@ -557,7 +555,7 @@ func (r *Reflector) list(stopCh <-chan struct{}) error {
}
resourceVersion = listMetaInterface.GetResourceVersion()
initTrace.Step("Resource version extracted")
items, err := meta.ExtractListWithAlloc(list)
items, err := meta.ExtractList(list)
if err != nil {
return fmt.Errorf("unable to understand list result %#v (%v)", list, err)
}
@@ -601,7 +599,7 @@ func (r *Reflector) watchList(stopCh <-chan struct{}) (watch.Interface, error) {
isErrorRetriableWithSideEffectsFn := func(err error) bool {
if canRetry := isWatchErrorRetriable(err); canRetry {
klog.V(2).Infof("%s: watch-list of %v returned %v - backing off", r.name, r.typeDescription, err)
<-r.backoffManager.Backoff().C()
<-r.initConnBackoffManager.Backoff().C()
return true
}
if isExpiredError(err) || isTooLargeResourceVersionError(err) {

View File

@@ -17,12 +17,10 @@ limitations under the License.
package cache
import (
"context"
"errors"
"fmt"
"math/rand"
"reflect"
goruntime "runtime"
"strconv"
"syscall"
"testing"
@@ -30,13 +28,10 @@ import (
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/utils/clock"
@@ -416,12 +411,12 @@ func TestReflectorListAndWatchInitConnBackoff(t *testing.T) {
},
}
r := &Reflector{
name: "test-reflector",
listerWatcher: lw,
store: NewFIFO(MetaNamespaceKeyFunc),
backoffManager: bm,
clock: fakeClock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
name: "test-reflector",
listerWatcher: lw,
store: NewFIFO(MetaNamespaceKeyFunc),
initConnBackoffManager: bm,
clock: fakeClock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
}
start := fakeClock.Now()
err := r.ListAndWatch(stopCh)
@@ -476,12 +471,12 @@ func TestBackoffOnTooManyRequests(t *testing.T) {
}
r := &Reflector{
name: "test-reflector",
listerWatcher: lw,
store: NewFIFO(MetaNamespaceKeyFunc),
backoffManager: bm,
clock: clock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
name: "test-reflector",
listerWatcher: lw,
store: NewFIFO(MetaNamespaceKeyFunc),
initConnBackoffManager: bm,
clock: clock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
}
stopCh := make(chan struct{})
@@ -545,12 +540,12 @@ func TestRetryInternalError(t *testing.T) {
}
r := &Reflector{
name: "test-reflector",
listerWatcher: lw,
store: NewFIFO(MetaNamespaceKeyFunc),
backoffManager: bm,
clock: fakeClock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
name: "test-reflector",
listerWatcher: lw,
store: NewFIFO(MetaNamespaceKeyFunc),
initConnBackoffManager: bm,
clock: fakeClock,
watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler),
}
r.MaxInternalErrorRetryDuration = tc.maxInternalDuration
@@ -1124,493 +1119,3 @@ func TestReflectorResourceVersionUpdate(t *testing.T) {
t.Errorf("Expected series of resource version updates of %#v but got: %#v", expectedRVs, s.resourceVersions)
}
}
const (
fakeItemsNum = 100
exemptObjectIndex = fakeItemsNum / 4
pageNum = 3
)
func getPodListItems(start int, numItems int) (string, string, *v1.PodList) {
out := &v1.PodList{
Items: make([]v1.Pod, numItems),
}
for i := 0; i < numItems; i++ {
out.Items[i] = v1.Pod{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Pod",
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("pod-%d", i+start),
Namespace: "default",
Labels: map[string]string{
"label-key-1": "label-value-1",
},
Annotations: map[string]string{
"annotations-key-1": "annotations-value-1",
},
},
Spec: v1.PodSpec{
Overhead: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("3"),
v1.ResourceMemory: resource.MustParse("8"),
},
NodeSelector: map[string]string{
"foo": "bar",
"baz": "quux",
},
Affinity: &v1.Affinity{
NodeAffinity: &v1.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
NodeSelectorTerms: []v1.NodeSelectorTerm{
{MatchExpressions: []v1.NodeSelectorRequirement{{Key: `foo`}}},
},
},
PreferredDuringSchedulingIgnoredDuringExecution: []v1.PreferredSchedulingTerm{
{Preference: v1.NodeSelectorTerm{MatchExpressions: []v1.NodeSelectorRequirement{{Key: `foo`}}}},
},
},
},
TopologySpreadConstraints: []v1.TopologySpreadConstraint{
{TopologyKey: `foo`},
},
HostAliases: []v1.HostAlias{
{IP: "1.1.1.1"},
{IP: "2.2.2.2"},
},
ImagePullSecrets: []v1.LocalObjectReference{
{Name: "secret1"},
{Name: "secret2"},
},
Containers: []v1.Container{
{
Name: "foobar",
Image: "alpine",
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
},
Limits: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("2"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10"),
},
},
},
{
Name: "foobar2",
Image: "alpine",
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("4"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("12"),
},
Limits: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("8"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("24"),
},
},
},
},
InitContainers: []v1.Container{
{
Name: "small-init",
Image: "alpine",
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
},
Limits: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
},
},
},
{
Name: "big-init",
Image: "alpine",
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("40"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("120"),
},
Limits: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("80"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("240"),
},
},
},
},
Hostname: fmt.Sprintf("node-%d", i),
},
Status: v1.PodStatus{
Phase: v1.PodRunning,
ContainerStatuses: []v1.ContainerStatus{
{
ContainerID: "docker://numbers",
Image: "alpine",
Name: "foobar",
Ready: false,
},
{
ContainerID: "docker://numbers",
Image: "alpine",
Name: "foobar2",
Ready: false,
},
},
InitContainerStatuses: []v1.ContainerStatus{
{
ContainerID: "docker://numbers",
Image: "alpine",
Name: "small-init",
Ready: false,
},
{
ContainerID: "docker://numbers",
Image: "alpine",
Name: "big-init",
Ready: false,
},
},
Conditions: []v1.PodCondition{
{
Type: v1.PodScheduled,
Status: v1.ConditionTrue,
Reason: "successfully",
Message: "sync pod successfully",
LastProbeTime: metav1.Now(),
LastTransitionTime: metav1.Now(),
},
},
},
}
}
return out.Items[0].GetName(), out.Items[exemptObjectIndex].GetName(), out
}
func getConfigmapListItems(start int, numItems int) (string, string, *v1.ConfigMapList) {
out := &v1.ConfigMapList{
Items: make([]v1.ConfigMap, numItems),
}
for i := 0; i < numItems; i++ {
out.Items[i] = v1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("cm-%d", i+start),
Namespace: "default",
Labels: map[string]string{
"label-key-1": "label-value-1",
},
Annotations: map[string]string{
"annotations-key-1": "annotations-value-1",
},
},
Data: map[string]string{
"data-1": "value-1",
"data-2": "value-2",
},
}
}
return out.Items[0].GetName(), out.Items[exemptObjectIndex].GetName(), out
}
type TestPagingPodsLW struct {
totalPageCount int
fetchedPageCount int
detectedObjectNameList []string
exemptObjectNameList []string
}
func newPageTestLW(totalPageNum int) *TestPagingPodsLW {
return &TestPagingPodsLW{
totalPageCount: totalPageNum,
fetchedPageCount: 0,
}
}
func (t *TestPagingPodsLW) List(options metav1.ListOptions) (runtime.Object, error) {
firstPodName, exemptPodName, list := getPodListItems(t.fetchedPageCount*fakeItemsNum, fakeItemsNum)
t.detectedObjectNameList = append(t.detectedObjectNameList, firstPodName)
t.exemptObjectNameList = append(t.exemptObjectNameList, exemptPodName)
t.fetchedPageCount++
if t.fetchedPageCount >= t.totalPageCount {
return list, nil
}
list.SetContinue("true")
return list, nil
}
func (t *TestPagingPodsLW) Watch(options metav1.ListOptions) (watch.Interface, error) {
return nil, nil
}
func TestReflectorListExtract(t *testing.T) {
store := NewStore(func(obj interface{}) (string, error) {
pod, ok := obj.(*v1.Pod)
if !ok {
return "", fmt.Errorf("expect *v1.Pod, but got %T", obj)
}
return pod.GetName(), nil
})
lw := newPageTestLW(5)
reflector := NewReflector(lw, &v1.Pod{}, store, 0)
reflector.WatchListPageSize = fakeItemsNum
// execute list to fill store
stopCh := make(chan struct{})
if err := reflector.list(stopCh); err != nil {
t.Fatal(err)
}
// We will not delete exemptPod,
// in order to see if the existence of this Pod causes other Pods that are not used to be unable to properly clear.
for _, podName := range lw.exemptObjectNameList {
_, exist, err := store.GetByKey(podName)
if err != nil || !exist {
t.Fatalf("%s should exist in pod store", podName)
}
}
// we will pay attention to whether the memory occupied by the first Pod is released
// Golang's can only be SetFinalizer for the first element of the array,
// so pod-0 will be the object of our attention
detectedPodAlreadyBeCleared := make(chan struct{}, len(lw.detectedObjectNameList))
for _, firstPodName := range lw.detectedObjectNameList {
_, exist, err := store.GetByKey(firstPodName)
if err != nil || !exist {
t.Fatalf("%s should exist in pod store", firstPodName)
}
firstPod, exist, err := store.GetByKey(firstPodName)
if err != nil || !exist {
t.Fatalf("%s should exist in pod store", firstPodName)
}
goruntime.SetFinalizer(firstPod, func(obj interface{}) {
t.Logf("%s already be gc\n", obj.(*v1.Pod).GetName())
detectedPodAlreadyBeCleared <- struct{}{}
})
}
storedObjectKeys := store.ListKeys()
for _, k := range storedObjectKeys {
// delete all Pods except the exempted Pods.
if sets.NewString(lw.exemptObjectNameList...).Has(k) {
continue
}
obj, exist, err := store.GetByKey(k)
if err != nil || !exist {
t.Fatalf("%s should exist in pod store", k)
}
if err := store.Delete(obj); err != nil {
t.Fatalf("delete object: %v", err)
}
goruntime.GC()
}
clearedNum := 0
for {
select {
case <-detectedPodAlreadyBeCleared:
clearedNum++
if clearedNum == len(lw.detectedObjectNameList) {
return
}
}
}
}
func BenchmarkExtractList(b *testing.B) {
_, _, podList := getPodListItems(0, fakeItemsNum)
_, _, configMapList := getConfigmapListItems(0, fakeItemsNum)
tests := []struct {
name string
list runtime.Object
}{
{
name: "PodList",
list: podList,
},
{
name: "ConfigMapList",
list: configMapList,
},
}
for _, tc := range tests {
b.Run(tc.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := meta.ExtractList(tc.list)
if err != nil {
b.Errorf("extract list: %v", err)
}
}
b.StopTimer()
})
}
}
func BenchmarkEachListItem(b *testing.B) {
_, _, podList := getPodListItems(0, fakeItemsNum)
_, _, configMapList := getConfigmapListItems(0, fakeItemsNum)
tests := []struct {
name string
list runtime.Object
}{
{
name: "PodList",
list: podList,
},
{
name: "ConfigMapList",
list: configMapList,
},
}
for _, tc := range tests {
b.Run(tc.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := meta.EachListItem(tc.list, func(object runtime.Object) error {
return nil
})
if err != nil {
b.Errorf("each list: %v", err)
}
}
b.StopTimer()
})
}
}
func BenchmarkExtractListWithAlloc(b *testing.B) {
_, _, podList := getPodListItems(0, fakeItemsNum)
_, _, configMapList := getConfigmapListItems(0, fakeItemsNum)
tests := []struct {
name string
list runtime.Object
}{
{
name: "PodList",
list: podList,
},
{
name: "ConfigMapList",
list: configMapList,
},
}
for _, tc := range tests {
b.Run(tc.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := meta.ExtractListWithAlloc(tc.list)
if err != nil {
b.Errorf("extract list with alloc: %v", err)
}
}
b.StopTimer()
})
}
}
func BenchmarkEachListItemWithAlloc(b *testing.B) {
_, _, podList := getPodListItems(0, fakeItemsNum)
_, _, configMapList := getConfigmapListItems(0, fakeItemsNum)
tests := []struct {
name string
list runtime.Object
}{
{
name: "PodList",
list: podList,
},
{
name: "ConfigMapList",
list: configMapList,
},
}
for _, tc := range tests {
b.Run(tc.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := meta.EachListItemWithAlloc(tc.list, func(object runtime.Object) error {
return nil
})
if err != nil {
b.Errorf("each list with alloc: %v", err)
}
}
b.StopTimer()
})
}
}
func BenchmarkReflectorList(b *testing.B) {
ctx, cancel := context.WithTimeout(context.Background(), wait.ForeverTestTimeout)
defer cancel()
store := NewStore(func(obj interface{}) (string, error) {
o, err := meta.Accessor(obj)
if err != nil {
return "", err
}
return o.GetName(), nil
})
_, _, podList := getPodListItems(0, fakeItemsNum)
_, _, configMapList := getConfigmapListItems(0, fakeItemsNum)
tests := []struct {
name string
sample func() interface{}
list runtime.Object
}{
{
name: "PodList",
sample: func() interface{} {
return v1.Pod{}
},
list: podList,
},
{
name: "ConfigMapList",
sample: func() interface{} {
return v1.ConfigMap{}
},
list: configMapList,
},
}
for _, tc := range tests {
b.Run(tc.name, func(b *testing.B) {
sample := tc.sample()
reflector := NewReflector(newPageTestLW(pageNum), &sample, store, 0)
reflector.WatchListPageSize = fakeItemsNum
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := reflector.list(ctx.Done())
if err != nil {
b.Fatalf("reflect list: %v", err)
}
}
b.StopTimer()
})
}
}

View File

@@ -459,30 +459,29 @@ func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) {
klog.Warningf("The sharedIndexInformer has started, run more than once is not allowed")
return
}
fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{
KnownObjects: s.indexer,
EmitDeltaTypeReplaced: true,
Transformer: s.transform,
})
cfg := &Config{
Queue: fifo,
ListerWatcher: s.listerWatcher,
ObjectType: s.objectType,
ObjectDescription: s.objectDescription,
FullResyncPeriod: s.resyncCheckPeriod,
RetryOnError: false,
ShouldResync: s.processor.shouldResync,
Process: s.HandleDeltas,
WatchErrorHandler: s.watchErrorHandler,
}
func() {
s.startedLock.Lock()
defer s.startedLock.Unlock()
fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{
KnownObjects: s.indexer,
EmitDeltaTypeReplaced: true,
Transformer: s.transform,
})
cfg := &Config{
Queue: fifo,
ListerWatcher: s.listerWatcher,
ObjectType: s.objectType,
ObjectDescription: s.objectDescription,
FullResyncPeriod: s.resyncCheckPeriod,
RetryOnError: false,
ShouldResync: s.processor.shouldResync,
Process: s.HandleDeltas,
WatchErrorHandler: s.watchErrorHandler,
}
s.controller = New(cfg)
s.controller.(*controller).clock = s.clock
s.started = true

View File

@@ -393,33 +393,6 @@ func TestSharedInformerErrorHandling(t *testing.T) {
close(stop)
}
// TestSharedInformerStartRace is a regression test to ensure there is no race between
// Run and SetWatchErrorHandler, and Run and SetTransform.
func TestSharedInformerStartRace(t *testing.T) {
source := fcache.NewFakeControllerSource()
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
stop := make(chan struct{})
go func() {
for {
select {
case <-stop:
return
default:
}
// Set dummy functions, just to test for race
informer.SetTransform(func(i interface{}) (interface{}, error) {
return i, nil
})
informer.SetWatchErrorHandler(func(r *Reflector, err error) {
})
}
}()
go informer.Run(stop)
close(stop)
}
func TestSharedInformerTransformer(t *testing.T) {
// source simulates an apiserver object endpoint.
source := fcache.NewFakeControllerSource()

31
tools/cache/store.go vendored
View File

@@ -21,7 +21,6 @@ import (
"strings"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Store is a generic object storage and processing interface. A
@@ -100,38 +99,20 @@ type ExplicitKey string
// The key uses the format <namespace>/<name> unless <namespace> is empty, then
// it's just <name>.
//
// Clients that want a structured alternative can use ObjectToName or MetaObjectToName.
// Note: this would not be a client that wants a key for a Store because those are
// necessarily strings.
//
// TODO maybe some day?: change Store to be keyed differently
// TODO: replace key-as-string with a key-as-struct so that this
// packing/unpacking won't be necessary.
func MetaNamespaceKeyFunc(obj interface{}) (string, error) {
if key, ok := obj.(ExplicitKey); ok {
return string(key), nil
}
objName, err := ObjectToName(obj)
if err != nil {
return "", err
}
return objName.String(), nil
}
// ObjectToName returns the structured name for the given object,
// if indeed it can be viewed as a metav1.Object.
func ObjectToName(obj interface{}) (ObjectName, error) {
meta, err := meta.Accessor(obj)
if err != nil {
return ObjectName{}, fmt.Errorf("object has no meta: %v", err)
return "", fmt.Errorf("object has no meta: %v", err)
}
return MetaObjectToName(meta), nil
}
// MetaObjectToName returns the structured name for the given object
func MetaObjectToName(obj metav1.Object) ObjectName {
if len(obj.GetNamespace()) > 0 {
return ObjectName{Namespace: obj.GetNamespace(), Name: obj.GetName()}
if len(meta.GetNamespace()) > 0 {
return meta.GetNamespace() + "/" + meta.GetName(), nil
}
return ObjectName{Namespace: "", Name: obj.GetName()}
return meta.GetName(), nil
}
// SplitMetaNamespaceKey returns the namespace and name that

View File

@@ -23,8 +23,6 @@ import (
"reflect"
"testing"
utiltesting "k8s.io/client-go/util/testing"
"sigs.k8s.io/yaml"
)
@@ -55,9 +53,11 @@ func newMergedConfig(certFile, certContent, keyFile, keyContent, caFile, caConte
func TestMinifySuccess(t *testing.T) {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
@@ -89,9 +89,11 @@ func TestMinifySuccess(t *testing.T) {
func TestMinifyMissingContext(t *testing.T) {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
mutatingConfig.CurrentContext = "missing"
@@ -105,9 +107,11 @@ func TestMinifyMissingContext(t *testing.T) {
func TestMinifyMissingCluster(t *testing.T) {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
delete(mutatingConfig.Clusters, mutatingConfig.Contexts[mutatingConfig.CurrentContext].Cluster)
@@ -121,9 +125,11 @@ func TestMinifyMissingCluster(t *testing.T) {
func TestMinifyMissingAuthInfo(t *testing.T) {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
delete(mutatingConfig.AuthInfos, mutatingConfig.Contexts[mutatingConfig.CurrentContext].AuthInfo)
@@ -137,9 +143,11 @@ func TestMinifyMissingAuthInfo(t *testing.T) {
func TestFlattenSuccess(t *testing.T) {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
certData := "cert"
keyData := "key"
@@ -200,9 +208,11 @@ func TestFlattenSuccess(t *testing.T) {
func Example_minifyAndShorten() {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(&testing.T{}, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
certData := "cert"
keyData := "key"
@@ -218,16 +228,19 @@ func Example_minifyAndShorten() {
// Output:
// clusters:
// cow-cluster:
// LocationOfOrigin: ""
// certificate-authority-data: DATA+OMITTED
// server: http://cow.org:8080
// contexts:
// federal-context:
// LocationOfOrigin: ""
// cluster: cow-cluster
// user: red-user
// current-context: federal-context
// preferences: {}
// users:
// red-user:
// LocationOfOrigin: ""
// client-certificate-data: DATA+OMITTED
// client-key-data: DATA+OMITTED
// token: REDACTED
@@ -235,9 +248,11 @@ func Example_minifyAndShorten() {
func TestShortenSuccess(t *testing.T) {
certFile, _ := os.CreateTemp("", "")
defer os.Remove(certFile.Name())
keyFile, _ := os.CreateTemp("", "")
defer os.Remove(keyFile.Name())
caFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile)
defer os.Remove(caFile.Name())
certData := "cert"
keyData := "key"

View File

@@ -67,7 +67,7 @@ type Preferences struct {
type Cluster struct {
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
// +k8s:conversion-gen=false
LocationOfOrigin string `json:"-"`
LocationOfOrigin string
// Server is the address of the kubernetes cluster (https://hostname:port).
Server string `json:"server"`
// TLSServerName is used to check server certificate. If TLSServerName is empty, the hostname used to contact the server is used.
@@ -107,7 +107,7 @@ type Cluster struct {
type AuthInfo struct {
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
// +k8s:conversion-gen=false
LocationOfOrigin string `json:"-"`
LocationOfOrigin string
// ClientCertificate is the path to a client cert file for TLS.
// +optional
ClientCertificate string `json:"client-certificate,omitempty"`
@@ -159,7 +159,7 @@ type AuthInfo struct {
type Context struct {
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
// +k8s:conversion-gen=false
LocationOfOrigin string `json:"-"`
LocationOfOrigin string
// Cluster is the name of the cluster for this context
Cluster string `json:"cluster"`
// AuthInfo is the name of the authInfo for this context
@@ -252,7 +252,7 @@ type ExecConfig struct {
// recommended as one of the prime benefits of exec plugins is that no secrets need
// to be stored directly in the kubeconfig.
// +k8s:conversion-gen=false
Config runtime.Object `json:"-"`
Config runtime.Object
// InteractiveMode determines this plugin's relationship with standard input. Valid
// values are "Never" (this exec plugin never uses standard input), "IfAvailable" (this
@@ -264,7 +264,7 @@ type ExecConfig struct {
// client.authentication.k8s.io/v1beta1, then this field is optional and defaults
// to "IfAvailable" when unset. Otherwise, this field is required.
// +optional
InteractiveMode ExecInteractiveMode `json:"interactiveMode,omitempty"`
InteractiveMode ExecInteractiveMode
// StdinUnavailable indicates whether the exec authenticator can pass standard
// input through to this exec plugin. For example, a higher level entity might be using
@@ -272,14 +272,14 @@ type ExecConfig struct {
// plugin to use standard input. This is kept here in order to keep all of the exec configuration
// together, but it is never serialized.
// +k8s:conversion-gen=false
StdinUnavailable bool `json:"-"`
StdinUnavailable bool
// StdinUnavailableMessage is an optional message to be displayed when the exec authenticator
// cannot successfully run this exec plugin because it needs to use standard input and
// StdinUnavailable is true. For example, a process that is already using standard input to
// read user instructions might set this to "used by my-program to read user instructions".
// +k8s:conversion-gen=false
StdinUnavailableMessage string `json:"-"`
StdinUnavailableMessage string
}
var _ fmt.Stringer = new(ExecConfig)

View File

@@ -94,21 +94,26 @@ func Example_ofOptionsConfig() {
// Output:
// clusters:
// alfa:
// LocationOfOrigin: ""
// certificate-authority: path/to/my/cert-ca-filename
// disable-compression: true
// insecure-skip-tls-verify: true
// server: https://alfa.org:8080
// bravo:
// LocationOfOrigin: ""
// server: https://bravo.org:8080
// contexts:
// alfa-as-black-mage:
// LocationOfOrigin: ""
// cluster: alfa
// namespace: zulu
// user: black-mage-via-auth-provider
// alfa-as-white-mage:
// LocationOfOrigin: ""
// cluster: alfa
// user: white-mage-via-cert
// bravo-as-black-mage:
// LocationOfOrigin: ""
// cluster: bravo
// namespace: yankee
// user: black-mage-via-auth-provider
@@ -117,14 +122,17 @@ func Example_ofOptionsConfig() {
// colors: true
// users:
// black-mage-via-auth-provider:
// LocationOfOrigin: ""
// auth-provider:
// config:
// foo: bar
// token: s3cr3t-t0k3n
// name: gcp
// red-mage-via-token:
// LocationOfOrigin: ""
// token: my-secret-token
// white-mage-via-cert:
// LocationOfOrigin: ""
// client-certificate: path/to/my/client-cert-filename
// client-key: path/to/my/client-key-filename
}

View File

@@ -22,8 +22,6 @@ import (
"strings"
"testing"
utiltesting "k8s.io/client-go/util/testing"
"github.com/imdario/mergo"
"k8s.io/apimachinery/pkg/runtime"
@@ -179,7 +177,7 @@ func TestCAOverridesCAData(t *testing.T) {
if err != nil {
t.Fatalf("could not create tempfile: %v", err)
}
defer utiltesting.CloseAndRemove(t, file)
defer os.Remove(file.Name())
config := createCAValidTestConfig()
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{
@@ -314,7 +312,8 @@ func TestModifyContext(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer utiltesting.CloseAndRemove(t, tempPath)
defer os.Remove(tempPath.Name())
pathOptions := NewDefaultPathOptions()
config := createValidTestConfig()
@@ -499,7 +498,7 @@ func TestBasicTokenFile(t *testing.T) {
t.Errorf("Unexpected error: %v", err)
return
}
defer utiltesting.CloseAndRemove(t, f)
defer os.Remove(f.Name())
if err := os.WriteFile(f.Name(), []byte(token), 0644); err != nil {
t.Errorf("Unexpected error: %v", err)
return
@@ -535,7 +534,7 @@ func TestPrecedenceTokenFile(t *testing.T) {
t.Errorf("Unexpected error: %v", err)
return
}
defer utiltesting.CloseAndRemove(t, f)
defer os.Remove(f.Name())
if err := os.WriteFile(f.Name(), []byte(token), 0644); err != nil {
t.Errorf("Unexpected error: %v", err)
return
@@ -924,7 +923,7 @@ users:
if err != nil {
t.Error(err)
}
defer utiltesting.CloseAndRemove(t, tmpfile)
defer os.Remove(tmpfile.Name())
if err := os.WriteFile(tmpfile.Name(), []byte(content), 0666); err != nil {
t.Error(err)
}

View File

@@ -128,28 +128,6 @@ type ClientConfigLoadingRules struct {
// WarnIfAllMissing indicates whether the configuration files pointed by KUBECONFIG environment variable are present or not.
// In case of missing files, it warns the user about the missing files.
WarnIfAllMissing bool
// Warner is the warning log callback to use in case of missing files.
Warner WarningHandler
}
// WarningHandler allows to set the logging function to use
type WarningHandler func(error)
func (handler WarningHandler) Warn(err error) {
if handler == nil {
klog.V(1).Info(err)
} else {
handler(err)
}
}
type MissingConfigError struct {
Missing []string
}
func (c MissingConfigError) Error() string {
return fmt.Sprintf("Config not found: %s", strings.Join(c.Missing, ", "))
}
// ClientConfigLoadingRules implements the ClientConfigLoader interface.
@@ -241,7 +219,7 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
}
if rules.WarnIfAllMissing && len(missingList) > 0 && len(kubeconfigs) == 0 {
rules.Warner.Warn(MissingConfigError{Missing: missingList})
klog.Warningf("Config not found: %s", strings.Join(missingList, ", "))
}
// first merge all of our maps

View File

@@ -18,7 +18,6 @@ package clientcmd
import (
"bytes"
"flag"
"fmt"
"os"
"path"
@@ -27,15 +26,12 @@ import (
"strings"
"testing"
utiltesting "k8s.io/client-go/util/testing"
"github.com/google/go-cmp/cmp"
"sigs.k8s.io/yaml"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"
"k8s.io/klog/v2"
)
var (
@@ -124,82 +120,19 @@ func TestNonExistentCommandLineFile(t *testing.T) {
}
func TestToleratingMissingFiles(t *testing.T) {
envVarValue := "bogus"
loadingRules := ClientConfigLoadingRules{
Precedence: []string{"bogus1", "bogus2", "bogus3"},
WarnIfAllMissing: true,
Warner: func(err error) { klog.Warning(err) },
Precedence: []string{"bogus1", "bogus2", "bogus3"},
}
buffer := &bytes.Buffer{}
klog.LogToStderr(false)
klog.SetOutput(buffer)
_, err := loadingRules.Load()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
klog.Flush()
expectedLog := fmt.Sprintf("Config not found: %s", envVarValue)
if !strings.Contains(buffer.String(), expectedLog) {
t.Fatalf("expected log: \"%s\"", expectedLog)
}
}
func TestWarningMissingFiles(t *testing.T) {
envVarValue := "bogus"
t.Setenv(RecommendedConfigPathEnvVar, envVarValue)
loadingRules := NewDefaultClientConfigLoadingRules()
buffer := &bytes.Buffer{}
flags := &flag.FlagSet{}
klog.InitFlags(flags)
flags.Set("v", "1")
klog.LogToStderr(false)
klog.SetOutput(buffer)
_, err := loadingRules.Load()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
klog.Flush()
expectedLog := fmt.Sprintf("Config not found: %s", envVarValue)
if !strings.Contains(buffer.String(), expectedLog) {
t.Fatalf("expected log: \"%s\"", expectedLog)
}
}
func TestNoWarningMissingFiles(t *testing.T) {
envVarValue := "bogus"
t.Setenv(RecommendedConfigPathEnvVar, envVarValue)
loadingRules := NewDefaultClientConfigLoadingRules()
buffer := &bytes.Buffer{}
flags := &flag.FlagSet{}
klog.InitFlags(flags)
flags.Set("v", "0")
klog.LogToStderr(false)
klog.SetOutput(buffer)
_, err := loadingRules.Load()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
klog.Flush()
logNotExpected := fmt.Sprintf("Config not found: %s", envVarValue)
if strings.Contains(buffer.String(), logNotExpected) {
t.Fatalf("log not expected: \"%s\"", logNotExpected)
}
}
func TestErrorReadingFile(t *testing.T) {
commandLineFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, commandLineFile)
defer os.Remove(commandLineFile.Name())
if err := os.WriteFile(commandLineFile.Name(), []byte("bogus value"), 0644); err != nil {
t.Fatalf("Error creating tempfile: %v", err)
@@ -240,8 +173,9 @@ func TestErrorReadingNonFile(t *testing.T) {
func TestConflictingCurrentContext(t *testing.T) {
commandLineFile, _ := os.CreateTemp("", "")
defer os.Remove(commandLineFile.Name())
envVarFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, commandLineFile, envVarFile)
defer os.Remove(envVarFile.Name())
mockCommandLineConfig := clientcmdapi.Config{
CurrentContext: "any-context-value",
@@ -314,13 +248,13 @@ preferences: {}
users: null
`)
if !bytes.Equal(expected, data) {
t.Error(cmp.Diff(string(expected), string(data)))
t.Error(diff.ObjectReflectDiff(string(expected), string(data)))
}
}
func TestLoadingEmptyMaps(t *testing.T) {
configFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, configFile)
defer os.Remove(configFile.Name())
mockConfig := clientcmdapi.Config{
CurrentContext: "any-context-value",
@@ -346,7 +280,7 @@ func TestLoadingEmptyMaps(t *testing.T) {
func TestDuplicateClusterName(t *testing.T) {
configFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, configFile)
defer os.Remove(configFile.Name())
err := os.WriteFile(configFile.Name(), []byte(`
kind: Config
@@ -388,7 +322,7 @@ users:
func TestDuplicateContextName(t *testing.T) {
configFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, configFile)
defer os.Remove(configFile.Name())
err := os.WriteFile(configFile.Name(), []byte(`
kind: Config
@@ -430,7 +364,7 @@ users:
func TestDuplicateUserName(t *testing.T) {
configFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, configFile)
defer os.Remove(configFile.Name())
err := os.WriteFile(configFile.Name(), []byte(`
kind: Config
@@ -470,7 +404,7 @@ users:
func TestDuplicateExtensionName(t *testing.T) {
configFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, configFile)
defer os.Remove(configFile.Name())
err := os.WriteFile(configFile.Name(), []byte(`
kind: Config
@@ -626,7 +560,7 @@ func TestResolveRelativePaths(t *testing.T) {
func TestMigratingFile(t *testing.T) {
sourceFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, sourceFile)
defer os.Remove(sourceFile.Name())
destinationFile, _ := os.CreateTemp("", "")
// delete the file so that we'll write to it
os.Remove(destinationFile.Name())
@@ -640,8 +574,9 @@ func TestMigratingFile(t *testing.T) {
if _, err := loadingRules.Load(); err != nil {
t.Errorf("unexpected error %v", err)
}
// the load should have recreated this file
defer utiltesting.CloseAndRemove(t, destinationFile)
defer os.Remove(destinationFile.Name())
sourceContent, err := os.ReadFile(sourceFile.Name())
if err != nil {
@@ -659,8 +594,9 @@ func TestMigratingFile(t *testing.T) {
func TestMigratingFileLeaveExistingFileAlone(t *testing.T) {
sourceFile, _ := os.CreateTemp("", "")
defer os.Remove(sourceFile.Name())
destinationFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, sourceFile, destinationFile)
defer os.Remove(destinationFile.Name())
WriteToFile(testConfigAlfa, sourceFile.Name())
@@ -686,7 +622,7 @@ func TestMigratingFileSourceMissingSkip(t *testing.T) {
sourceFilename := "some-missing-file"
destinationFile, _ := os.CreateTemp("", "")
// delete the file so that we'll write to it
utiltesting.CloseAndRemove(t, destinationFile)
os.Remove(destinationFile.Name())
loadingRules := ClientConfigLoadingRules{
MigrationRules: map[string]string{destinationFile.Name(): sourceFilename},
@@ -703,7 +639,7 @@ func TestMigratingFileSourceMissingSkip(t *testing.T) {
func TestFileLocking(t *testing.T) {
f, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, f)
defer os.Remove(f.Name())
err := lockFile(f.Name())
if err != nil {
@@ -719,8 +655,9 @@ func TestFileLocking(t *testing.T) {
func Example_noMergingOnExplicitPaths() {
commandLineFile, _ := os.CreateTemp("", "")
defer os.Remove(commandLineFile.Name())
envVarFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(&testing.T{}, commandLineFile, envVarFile)
defer os.Remove(envVarFile.Name())
WriteToFile(testConfigAlfa, commandLineFile.Name())
WriteToFile(testConfigConflictAlfa, envVarFile.Name())
@@ -767,8 +704,9 @@ func Example_noMergingOnExplicitPaths() {
func Example_mergingSomeWithConflict() {
commandLineFile, _ := os.CreateTemp("", "")
defer os.Remove(commandLineFile.Name())
envVarFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(&testing.T{}, commandLineFile, envVarFile)
defer os.Remove(envVarFile.Name())
WriteToFile(testConfigAlfa, commandLineFile.Name())
WriteToFile(testConfigConflictAlfa, envVarFile.Name())
@@ -822,10 +760,13 @@ func Example_mergingSomeWithConflict() {
func Example_mergingEverythingNoConflicts() {
commandLineFile, _ := os.CreateTemp("", "")
defer os.Remove(commandLineFile.Name())
envVarFile, _ := os.CreateTemp("", "")
defer os.Remove(envVarFile.Name())
currentDirFile, _ := os.CreateTemp("", "")
defer os.Remove(currentDirFile.Name())
homeDirFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(&testing.T{}, commandLineFile, envVarFile, currentDirFile, homeDirFile)
defer os.Remove(homeDirFile.Name())
WriteToFile(testConfigAlfa, commandLineFile.Name())
WriteToFile(testConfigBravo, envVarFile.Name())
@@ -956,9 +897,12 @@ func TestLoadingGetLoadingPrecedence(t *testing.T) {
},
}
kubeconfig := os.Getenv("KUBECONFIG")
defer os.Setenv("KUBECONFIG", kubeconfig)
for name, test := range testCases {
t.Run(name, func(t *testing.T) {
t.Setenv("KUBECONFIG", test.env)
os.Setenv("KUBECONFIG", test.env)
rules := test.rules
if rules == nil {
rules = NewDefaultClientConfigLoadingRules()

View File

@@ -23,8 +23,6 @@ import (
"strings"
"testing"
utiltesting "k8s.io/client-go/util/testing"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)
@@ -298,7 +296,7 @@ func TestValidateCleanClusterInfo(t *testing.T) {
func TestValidateCleanWithCAClusterInfo(t *testing.T) {
tempFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, tempFile)
defer os.Remove(tempFile.Name())
config := clientcmdapi.NewConfig()
config.Clusters["clean"] = &clientcmdapi.Cluster{
@@ -341,7 +339,7 @@ func TestValidateCertFilesNotFoundAuthInfo(t *testing.T) {
func TestValidateCertDataOverridesFiles(t *testing.T) {
tempFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, tempFile)
defer os.Remove(tempFile.Name())
config := clientcmdapi.NewConfig()
config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{
@@ -361,7 +359,7 @@ func TestValidateCertDataOverridesFiles(t *testing.T) {
func TestValidateCleanCertFilesAuthInfo(t *testing.T) {
tempFile, _ := os.CreateTemp("", "")
defer utiltesting.CloseAndRemove(t, tempFile)
defer os.Remove(tempFile.Name())
config := clientcmdapi.NewConfig()
config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{
@@ -750,31 +748,37 @@ func TestErrConfigurationInvalidWithErrorsIs(t *testing.T) {
err error
matchAgainst error
expectMatch bool
}{{
name: "no match",
err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")},
matchAgainst: fmt.Errorf("no entry %s", "here"),
}, {
name: "match via .Is()",
err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}},
matchAgainst: errors.New("unauthorized"),
expectMatch: true,
}, {
name: "match via equality",
err: errConfigurationInvalid{errors.New("err"), someError{}},
matchAgainst: someError{},
expectMatch: true,
}, {
name: "match via nested aggregate",
err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}},
matchAgainst: someError{},
expectMatch: true,
}, {
name: "match via wrapped aggregate",
err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}),
matchAgainst: someError{},
expectMatch: true,
}}
}{
{
name: "no match",
err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")},
matchAgainst: fmt.Errorf("no entry %s", "here"),
},
{
name: "match via .Is()",
err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}},
matchAgainst: errors.New("unauthorized"),
expectMatch: true,
},
{
name: "match via equality",
err: errConfigurationInvalid{errors.New("err"), someError{}},
matchAgainst: someError{},
expectMatch: true,
},
{
name: "match via nested aggregate",
err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}},
matchAgainst: someError{},
expectMatch: true,
},
{
name: "match via wrapped aggregate",
err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}),
matchAgainst: someError{},
expectMatch: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {

View File

@@ -21,9 +21,9 @@ import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
eventsv1 "k8s.io/api/events/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/kubernetes/fake"
)
@@ -96,7 +96,7 @@ func TestRecordEventToSink(t *testing.T) {
recordedEvent := recordedEvents.Items[0]
if !reflect.DeepEqual(recordedEvent, tc.expectedRecordedEvent) {
t.Errorf("expected to have recorded Event: %#+v, got: %#+v\n diff: %s", tc.expectedRecordedEvent, recordedEvent, cmp.Diff(tc.expectedRecordedEvent, recordedEvent))
t.Errorf("expected to have recorded Event: %#+v, got: %#+v\n diff: %s", tc.expectedRecordedEvent, recordedEvent, diff.ObjectReflectDiff(tc.expectedRecordedEvent, recordedEvent))
}
})
}

View File

@@ -99,11 +99,6 @@ func NewLeaderElector(lec LeaderElectionConfig) (*LeaderElector, error) {
if lec.Lock == nil {
return nil, fmt.Errorf("Lock must not be nil.")
}
id := lec.Lock.Identity()
if id == "" {
return nil, fmt.Errorf("Lock identity is empty")
}
le := LeaderElector{
config: lec,
clock: clock.RealClock{},

View File

@@ -24,21 +24,19 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
coordinationv1 "k8s.io/api/coordination/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/fake"
fakeclient "k8s.io/client-go/testing"
rl "k8s.io/client-go/tools/leaderelection/resourcelock"
"k8s.io/client-go/tools/record"
"k8s.io/utils/clock"
"github.com/stretchr/testify/assert"
)
func createLockObject(t *testing.T, objectType, namespace, name string, record *rl.LeaderElectionRecord) (obj runtime.Object) {
@@ -373,30 +371,551 @@ func TestLeaseSpecToLeaderElectionRecordRoundTrip(t *testing.T) {
newSpec := rl.LeaderElectionRecordToLeaseSpec(oldRecord)
if !equality.Semantic.DeepEqual(oldSpec, newSpec) {
t.Errorf("diff: %v", cmp.Diff(oldSpec, newSpec))
t.Errorf("diff: %v", diff.ObjectReflectDiff(oldSpec, newSpec))
}
newRecord := rl.LeaseSpecToLeaderElectionRecord(&newSpec)
if !equality.Semantic.DeepEqual(oldRecord, newRecord) {
t.Errorf("diff: %v", cmp.Diff(oldRecord, newRecord))
t.Errorf("diff: %v", diff.ObjectReflectDiff(oldRecord, newRecord))
}
}
func multiLockType(t *testing.T, objectType string) (primaryType, secondaryType string) {
switch objectType {
case rl.EndpointsLeasesResourceLock:
return "endpoints", rl.LeasesResourceLock
case rl.ConfigMapsLeasesResourceLock:
return "configmaps", rl.LeasesResourceLock
default:
t.Fatal("unexpected objType:" + objectType)
}
return
}
func GetRawRecordOrDie(t *testing.T, objectType string, ler rl.LeaderElectionRecord) (ret []byte) {
var err error
switch objectType {
case "leases":
case "endpoints", "configmaps", "leases":
ret, err = json.Marshal(ler)
if err != nil {
t.Fatalf("lock %s get raw record %v failed: %v", objectType, ler, err)
}
case "endpointsleases", "configmapsleases":
recordBytes, err := json.Marshal(ler)
if err != nil {
t.Fatalf("lock %s get raw record %v failed: %v", objectType, ler, err)
}
ret = rl.ConcatRawRecord(recordBytes, recordBytes)
default:
t.Fatal("unexpected objType:" + objectType)
}
return
}
func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
clock := clock.RealClock{}
future := clock.Now().Add(1000 * time.Hour)
past := clock.Now().Add(-1000 * time.Hour)
primaryType, secondaryType := multiLockType(t, objectType)
tests := []struct {
name string
observedRecord rl.LeaderElectionRecord
observedRawRecord []byte
observedTime time.Time
reactors []Reactor
expectedEvents []string
expectSuccess bool
transitionLeader bool
outHolder string
}{
{
name: "acquire from no object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
},
},
{
verb: "create",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.CreateAction).GetObject(), nil
},
},
{
verb: "create",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.CreateAction).GetObject(), nil
},
},
},
expectSuccess: true,
outHolder: "baz",
},
{
name: "acquire from unled old object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
},
},
{
verb: "update",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
},
},
{
verb: "create",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.CreateAction).GetObject(), nil
},
},
},
expectSuccess: true,
transitionLeader: true,
outHolder: "baz",
},
{
name: "acquire from unled transition object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
},
},
{
verb: "update",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
},
},
{
verb: "update",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
},
expectSuccess: true,
transitionLeader: true,
outHolder: "baz",
},
{
name: "acquire from led, unack old object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
},
},
{
verb: "update",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "create",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.CreateAction).GetObject(), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
observedRawRecord: GetRawRecordOrDie(t, primaryType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
observedTime: past,
expectSuccess: true,
transitionLeader: true,
outHolder: "baz",
},
{
name: "acquire from led, unack transition object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "update",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "update",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
observedTime: past,
expectSuccess: true,
transitionLeader: true,
outHolder: "baz",
},
{
name: "acquire from conflict led, ack transition object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
observedTime: future,
expectSuccess: false,
outHolder: rl.UnknownLeader,
},
{
name: "acquire from led, unack unknown object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
},
},
{
verb: "update",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
},
},
{
verb: "update",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader},
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}),
observedTime: past,
expectSuccess: true,
transitionLeader: true,
outHolder: "baz",
},
{
name: "don't acquire from led, ack old object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
observedRawRecord: GetRawRecordOrDie(t, primaryType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
observedTime: future,
expectSuccess: false,
outHolder: "bing",
},
{
name: "don't acquire from led, acked new object, observe new record",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
observedRawRecord: GetRawRecordOrDie(t, secondaryType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
observedTime: future,
expectSuccess: false,
outHolder: rl.UnknownLeader,
},
{
name: "don't acquire from led, acked new object, observe transition record",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
observedTime: future,
expectSuccess: false,
outHolder: "bing",
},
{
name: "renew already required object",
reactors: []Reactor{
{
verb: "get",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
},
},
{
verb: "update",
objectType: primaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
{
verb: "get",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
},
},
{
verb: "update",
objectType: secondaryType,
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(fakeclient.UpdateAction).GetObject(), nil
},
},
},
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "baz"},
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "baz"}),
observedTime: future,
expectSuccess: true,
outHolder: "baz",
},
}
for i := range tests {
test := &tests[i]
t.Run(test.name, func(t *testing.T) {
// OnNewLeader is called async so we have to wait for it.
var wg sync.WaitGroup
wg.Add(1)
var reportedLeader string
recorder := record.NewFakeRecorder(100)
resourceLockConfig := rl.ResourceLockConfig{
Identity: "baz",
EventRecorder: recorder,
}
c := &fake.Clientset{}
for _, reactor := range test.reactors {
c.AddReactor(reactor.verb, reactor.objectType, reactor.reaction)
}
c.AddReactor("*", "*", func(action fakeclient.Action) (bool, runtime.Object, error) {
t.Errorf("unreachable action. testclient called too many times: %+v", action)
return true, nil, fmt.Errorf("unreachable action")
})
lock, err := rl.New(objectType, "foo", "bar", c.CoreV1(), c.CoordinationV1(), resourceLockConfig)
if err != nil {
t.Fatalf("Couldn't create lock: %v", err)
}
lec := LeaderElectionConfig{
Lock: lock,
LeaseDuration: 10 * time.Second,
Callbacks: LeaderCallbacks{
OnNewLeader: func(l string) {
defer wg.Done()
reportedLeader = l
},
},
}
le := &LeaderElector{
config: lec,
observedRecord: test.observedRecord,
observedRawRecord: test.observedRawRecord,
observedTime: test.observedTime,
clock: clock,
}
if test.expectSuccess != le.tryAcquireOrRenew(context.Background()) {
t.Errorf("unexpected result of tryAcquireOrRenew: [succeeded=%v]", !test.expectSuccess)
}
le.observedRecord.AcquireTime = metav1.Time{}
le.observedRecord.RenewTime = metav1.Time{}
if le.observedRecord.HolderIdentity != test.outHolder {
t.Errorf("expected holder:\n\t%+v\ngot:\n\t%+v", test.outHolder, le.observedRecord.HolderIdentity)
}
if len(test.reactors) != len(c.Actions()) {
t.Errorf("wrong number of api interactions")
}
if test.transitionLeader && le.observedRecord.LeaderTransitions != 1 {
t.Errorf("leader should have transitioned but did not")
}
if !test.transitionLeader && le.observedRecord.LeaderTransitions != 0 {
t.Errorf("leader should not have transitioned but did")
}
le.maybeReportTransition()
wg.Wait()
if reportedLeader != test.outHolder {
t.Errorf("reported leader was not the new leader. expected %q, got %q", test.outHolder, reportedLeader)
}
assertEqualEvents(t, test.expectedEvents, recorder.Events)
})
}
}
// Will test leader election using endpointsleases as the resource
func TestTryAcquireOrRenewEndpointsLeases(t *testing.T) {
testTryAcquireOrRenewMultiLock(t, "endpointsleases")
}
// Will test leader election using configmapsleases as the resource
func TestTryAcquireOrRenewConfigMapsLeases(t *testing.T) {
testTryAcquireOrRenewMultiLock(t, "configmapsleases")
}
func testReleaseLease(t *testing.T, objectType string) {
tests := []struct {
name string
@@ -755,41 +1274,6 @@ func testReleaseOnCancellation(t *testing.T, objectType string) {
}
}
func TestLeaderElectionConfigValidation(t *testing.T) {
resourceLockConfig := rl.ResourceLockConfig{
Identity: "baz",
}
lock := &rl.LeaseLock{
LockConfig: resourceLockConfig,
}
lec := LeaderElectionConfig{
Lock: lock,
LeaseDuration: 15 * time.Second,
RenewDeadline: 2 * time.Second,
RetryPeriod: 1 * time.Second,
ReleaseOnCancel: true,
Callbacks: LeaderCallbacks{
OnNewLeader: func(identity string) {},
OnStoppedLeading: func() {},
OnStartedLeading: func(context.Context) {},
},
}
_, err := NewLeaderElector(lec)
assert.NoError(t, err)
// Invalid lock identity
resourceLockConfig.Identity = ""
lock.LockConfig = resourceLockConfig
lec.Lock = lock
_, err = NewLeaderElector(lec)
assert.Error(t, err, fmt.Errorf("Lock identity is empty"))
}
func assertEqualEvents(t *testing.T, expected []string, actual <-chan string) {
c := time.After(wait.ForeverTestTimeout)
for _, e := range expected {

View File

@@ -0,0 +1,126 @@
/*
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 resourcelock
import (
"context"
"encoding/json"
"errors"
"fmt"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
)
// TODO: This is almost a exact replica of Endpoints lock.
// going forwards as we self host more and more components
// and use ConfigMaps as the means to pass that configuration
// data we will likely move to deprecate the Endpoints lock.
type configMapLock struct {
// ConfigMapMeta should contain a Name and a Namespace of a
// ConfigMapMeta object that the LeaderElector will attempt to lead.
ConfigMapMeta metav1.ObjectMeta
Client corev1client.ConfigMapsGetter
LockConfig ResourceLockConfig
cm *v1.ConfigMap
}
// Get returns the election record from a ConfigMap Annotation
func (cml *configMapLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) {
var record LeaderElectionRecord
cm, err := cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Get(ctx, cml.ConfigMapMeta.Name, metav1.GetOptions{})
if err != nil {
return nil, nil, err
}
cml.cm = cm
if cml.cm.Annotations == nil {
cml.cm.Annotations = make(map[string]string)
}
recordStr, found := cml.cm.Annotations[LeaderElectionRecordAnnotationKey]
recordBytes := []byte(recordStr)
if found {
if err := json.Unmarshal(recordBytes, &record); err != nil {
return nil, nil, err
}
}
return &record, recordBytes, nil
}
// Create attempts to create a LeaderElectionRecord annotation
func (cml *configMapLock) Create(ctx context.Context, ler LeaderElectionRecord) error {
recordBytes, err := json.Marshal(ler)
if err != nil {
return err
}
cml.cm, err = cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Create(ctx, &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: cml.ConfigMapMeta.Name,
Namespace: cml.ConfigMapMeta.Namespace,
Annotations: map[string]string{
LeaderElectionRecordAnnotationKey: string(recordBytes),
},
},
}, metav1.CreateOptions{})
return err
}
// Update will update an existing annotation on a given resource.
func (cml *configMapLock) Update(ctx context.Context, ler LeaderElectionRecord) error {
if cml.cm == nil {
return errors.New("configmap not initialized, call get or create first")
}
recordBytes, err := json.Marshal(ler)
if err != nil {
return err
}
if cml.cm.Annotations == nil {
cml.cm.Annotations = make(map[string]string)
}
cml.cm.Annotations[LeaderElectionRecordAnnotationKey] = string(recordBytes)
cm, err := cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Update(ctx, cml.cm, metav1.UpdateOptions{})
if err != nil {
return err
}
cml.cm = cm
return nil
}
// RecordEvent in leader election while adding meta-data
func (cml *configMapLock) RecordEvent(s string) {
if cml.LockConfig.EventRecorder == nil {
return
}
events := fmt.Sprintf("%v %v", cml.LockConfig.Identity, s)
subject := &v1.ConfigMap{ObjectMeta: cml.cm.ObjectMeta}
// Populate the type meta, so we don't have to get it from the schema
subject.Kind = "ConfigMap"
subject.APIVersion = v1.SchemeGroupVersion.String()
cml.LockConfig.EventRecorder.Eventf(subject, v1.EventTypeNormal, "LeaderElection", events)
}
// Describe is used to convert details on current resource lock
// into a string
func (cml *configMapLock) Describe() string {
return fmt.Sprintf("%v/%v", cml.ConfigMapMeta.Namespace, cml.ConfigMapMeta.Name)
}
// Identity returns the Identity of the lock
func (cml *configMapLock) Identity() string {
return cml.LockConfig.Identity
}

View File

@@ -0,0 +1,121 @@
/*
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 resourcelock
import (
"context"
"encoding/json"
"errors"
"fmt"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
)
type endpointsLock struct {
// EndpointsMeta should contain a Name and a Namespace of an
// Endpoints object that the LeaderElector will attempt to lead.
EndpointsMeta metav1.ObjectMeta
Client corev1client.EndpointsGetter
LockConfig ResourceLockConfig
e *v1.Endpoints
}
// Get returns the election record from a Endpoints Annotation
func (el *endpointsLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) {
var record LeaderElectionRecord
ep, err := el.Client.Endpoints(el.EndpointsMeta.Namespace).Get(ctx, el.EndpointsMeta.Name, metav1.GetOptions{})
if err != nil {
return nil, nil, err
}
el.e = ep
if el.e.Annotations == nil {
el.e.Annotations = make(map[string]string)
}
recordStr, found := el.e.Annotations[LeaderElectionRecordAnnotationKey]
recordBytes := []byte(recordStr)
if found {
if err := json.Unmarshal(recordBytes, &record); err != nil {
return nil, nil, err
}
}
return &record, recordBytes, nil
}
// Create attempts to create a LeaderElectionRecord annotation
func (el *endpointsLock) Create(ctx context.Context, ler LeaderElectionRecord) error {
recordBytes, err := json.Marshal(ler)
if err != nil {
return err
}
el.e, err = el.Client.Endpoints(el.EndpointsMeta.Namespace).Create(ctx, &v1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
Name: el.EndpointsMeta.Name,
Namespace: el.EndpointsMeta.Namespace,
Annotations: map[string]string{
LeaderElectionRecordAnnotationKey: string(recordBytes),
},
},
}, metav1.CreateOptions{})
return err
}
// Update will update and existing annotation on a given resource.
func (el *endpointsLock) Update(ctx context.Context, ler LeaderElectionRecord) error {
if el.e == nil {
return errors.New("endpoint not initialized, call get or create first")
}
recordBytes, err := json.Marshal(ler)
if err != nil {
return err
}
if el.e.Annotations == nil {
el.e.Annotations = make(map[string]string)
}
el.e.Annotations[LeaderElectionRecordAnnotationKey] = string(recordBytes)
e, err := el.Client.Endpoints(el.EndpointsMeta.Namespace).Update(ctx, el.e, metav1.UpdateOptions{})
if err != nil {
return err
}
el.e = e
return nil
}
// RecordEvent in leader election while adding meta-data
func (el *endpointsLock) RecordEvent(s string) {
if el.LockConfig.EventRecorder == nil {
return
}
events := fmt.Sprintf("%v %v", el.LockConfig.Identity, s)
subject := &v1.Endpoints{ObjectMeta: el.e.ObjectMeta}
// Populate the type meta, so we don't have to get it from the schema
subject.Kind = "Endpoints"
subject.APIVersion = v1.SchemeGroupVersion.String()
el.LockConfig.EventRecorder.Eventf(subject, v1.EventTypeNormal, "LeaderElection", events)
}
// Describe is used to convert details on current resource lock
// into a string
func (el *endpointsLock) Describe() string {
return fmt.Sprintf("%v/%v", el.EndpointsMeta.Namespace, el.EndpointsMeta.Name)
}
// Identity returns the Identity of the lock
func (el *endpointsLock) Identity() string {
return el.LockConfig.Identity
}

View File

@@ -34,7 +34,7 @@ const (
endpointsResourceLock = "endpoints"
configMapsResourceLock = "configmaps"
LeasesResourceLock = "leases"
// When using endpointsLeasesResourceLock, you need to ensure that
// When using EndpointsLeasesResourceLock, you need to ensure that
// API Priority & Fairness is configured with non-default flow-schema
// that will catch the necessary operations on leader-election related
// endpoint objects.
@@ -67,8 +67,8 @@ const (
// serviceAccount:
// name: '*'
// namespace: kube-system
endpointsLeasesResourceLock = "endpointsleases"
// When using configMapsLeasesResourceLock, you need to ensure that
EndpointsLeasesResourceLock = "endpointsleases"
// When using ConfigMapsLeasesResourceLock, you need to ensure that
// API Priority & Fairness is configured with non-default flow-schema
// that will catch the necessary operations on leader-election related
// configmap objects.
@@ -101,7 +101,7 @@ const (
// serviceAccount:
// name: '*'
// namespace: kube-system
configMapsLeasesResourceLock = "configmapsleases"
ConfigMapsLeasesResourceLock = "configmapsleases"
)
// LeaderElectionRecord is the record that is stored in the leader election annotation.
@@ -164,6 +164,22 @@ type Interface interface {
// Manufacture will create a lock of a given type according to the input parameters
func New(lockType string, ns string, name string, coreClient corev1.CoreV1Interface, coordinationClient coordinationv1.CoordinationV1Interface, rlc ResourceLockConfig) (Interface, error) {
endpointsLock := &endpointsLock{
EndpointsMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
},
Client: coreClient,
LockConfig: rlc,
}
configmapLock := &configMapLock{
ConfigMapMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
},
Client: coreClient,
LockConfig: rlc,
}
leaseLock := &LeaseLock{
LeaseMeta: metav1.ObjectMeta{
Namespace: ns,
@@ -174,15 +190,21 @@ func New(lockType string, ns string, name string, coreClient corev1.CoreV1Interf
}
switch lockType {
case endpointsResourceLock:
return nil, fmt.Errorf("endpoints lock is removed, migrate to %s (using version v0.27.x)", endpointsLeasesResourceLock)
return nil, fmt.Errorf("endpoints lock is removed, migrate to %s", EndpointsLeasesResourceLock)
case configMapsResourceLock:
return nil, fmt.Errorf("configmaps lock is removed, migrate to %s (using version v0.27.x)", configMapsLeasesResourceLock)
return nil, fmt.Errorf("configmaps lock is removed, migrate to %s", ConfigMapsLeasesResourceLock)
case LeasesResourceLock:
return leaseLock, nil
case endpointsLeasesResourceLock:
return nil, fmt.Errorf("endpointsleases lock is removed, migrate to %s", LeasesResourceLock)
case configMapsLeasesResourceLock:
return nil, fmt.Errorf("configmapsleases lock is removed, migrated to %s", LeasesResourceLock)
case EndpointsLeasesResourceLock:
return &MultiLock{
Primary: endpointsLock,
Secondary: leaseLock,
}, nil
case ConfigMapsLeasesResourceLock:
return &MultiLock{
Primary: configmapLock,
Secondary: leaseLock,
}, nil
default:
return nil, fmt.Errorf("Invalid lock-type %s", lockType)
}

View File

@@ -42,10 +42,6 @@ type LatencyMetric interface {
Observe(ctx context.Context, verb string, u url.URL, latency time.Duration)
}
type ResolverLatencyMetric interface {
Observe(ctx context.Context, host string, latency time.Duration)
}
// SizeMetric observes client response size partitioned by verb and host.
type SizeMetric interface {
Observe(ctx context.Context, verb string, host string, size float64)
@@ -68,17 +64,6 @@ type RetryMetric interface {
IncrementRetry(ctx context.Context, code string, method string, host string)
}
// TransportCacheMetric shows the number of entries in the internal transport cache
type TransportCacheMetric interface {
Observe(value int)
}
// TransportCreateCallsMetric counts the number of times a transport is created
// partitioned by the result of the cache: hit, miss, uncacheable
type TransportCreateCallsMetric interface {
Increment(result string)
}
var (
// ClientCertExpiry is the expiry time of a client certificate
ClientCertExpiry ExpiryMetric = noopExpiry{}
@@ -86,8 +71,6 @@ var (
ClientCertRotationAge DurationMetric = noopDuration{}
// RequestLatency is the latency metric that rest clients will update.
RequestLatency LatencyMetric = noopLatency{}
// ResolverLatency is the latency metric that DNS resolver will update
ResolverLatency ResolverLatencyMetric = noopResolverLatency{}
// RequestSize is the request size metric that rest clients will update.
RequestSize SizeMetric = noopSize{}
// ResponseSize is the response size metric that rest clients will update.
@@ -102,12 +85,6 @@ var (
// RequestRetry is the retry metric that tracks the number of
// retries sent to the server.
RequestRetry RetryMetric = noopRetry{}
// TransportCacheEntries is the metric that tracks the number of entries in the
// internal transport cache.
TransportCacheEntries TransportCacheMetric = noopTransportCache{}
// TransportCreateCalls is the metric that counts the number of times a new transport
// is created
TransportCreateCalls TransportCreateCallsMetric = noopTransportCreateCalls{}
)
// RegisterOpts contains all the metrics to register. Metrics may be nil.
@@ -115,15 +92,12 @@ type RegisterOpts struct {
ClientCertExpiry ExpiryMetric
ClientCertRotationAge DurationMetric
RequestLatency LatencyMetric
ResolverLatency ResolverLatencyMetric
RequestSize SizeMetric
ResponseSize SizeMetric
RateLimiterLatency LatencyMetric
RequestResult ResultMetric
ExecPluginCalls CallsMetric
RequestRetry RetryMetric
TransportCacheEntries TransportCacheMetric
TransportCreateCalls TransportCreateCallsMetric
}
// Register registers metrics for the rest client to use. This can
@@ -139,9 +113,6 @@ func Register(opts RegisterOpts) {
if opts.RequestLatency != nil {
RequestLatency = opts.RequestLatency
}
if opts.ResolverLatency != nil {
ResolverLatency = opts.ResolverLatency
}
if opts.RequestSize != nil {
RequestSize = opts.RequestSize
}
@@ -160,12 +131,6 @@ func Register(opts RegisterOpts) {
if opts.RequestRetry != nil {
RequestRetry = opts.RequestRetry
}
if opts.TransportCacheEntries != nil {
TransportCacheEntries = opts.TransportCacheEntries
}
if opts.TransportCreateCalls != nil {
TransportCreateCalls = opts.TransportCreateCalls
}
})
}
@@ -181,11 +146,6 @@ type noopLatency struct{}
func (noopLatency) Observe(context.Context, string, url.URL, time.Duration) {}
type noopResolverLatency struct{}
func (n noopResolverLatency) Observe(ctx context.Context, host string, latency time.Duration) {
}
type noopSize struct{}
func (noopSize) Observe(context.Context, string, string, float64) {}
@@ -201,11 +161,3 @@ func (noopCalls) Increment(int, string) {}
type noopRetry struct{}
func (noopRetry) IncrementRetry(context.Context, string, string, string) {}
type noopTransportCache struct{}
func (noopTransportCache) Observe(int) {}
type noopTransportCreateCalls struct{}
func (noopTransportCreateCalls) Increment(string) {}

View File

@@ -73,23 +73,7 @@ func New(fn ListPageFunc) *ListPager {
// List returns a single list object, but attempts to retrieve smaller chunks from the
// server to reduce the impact on the server. If the chunk attempt fails, it will load
// the full list instead. The Limit field on options, if unset, will default to the page size.
//
// If items in the returned list are retained for different durations, and you want to avoid
// retaining the whole slice returned by p.PageFn as long as any item is referenced,
// use ListWithAlloc instead.
func (p *ListPager) List(ctx context.Context, options metav1.ListOptions) (runtime.Object, bool, error) {
return p.list(ctx, options, false)
}
// ListWithAlloc works like List, but avoids retaining references to the items slice returned by p.PageFn.
// It does this by making a shallow copy of non-pointer items in the slice returned by p.PageFn.
//
// If the items in the returned list are not retained, or are retained for the same duration, use List instead for memory efficiency.
func (p *ListPager) ListWithAlloc(ctx context.Context, options metav1.ListOptions) (runtime.Object, bool, error) {
return p.list(ctx, options, true)
}
func (p *ListPager) list(ctx context.Context, options metav1.ListOptions, allocNew bool) (runtime.Object, bool, error) {
if options.Limit == 0 {
options.Limit = p.PageSize
}
@@ -139,11 +123,7 @@ func (p *ListPager) list(ctx context.Context, options metav1.ListOptions, allocN
list.ResourceVersion = m.GetResourceVersion()
list.SelfLink = m.GetSelfLink()
}
eachListItemFunc := meta.EachListItem
if allocNew {
eachListItemFunc = meta.EachListItemWithAlloc
}
if err := eachListItemFunc(obj, func(obj runtime.Object) error {
if err := meta.EachListItem(obj, func(obj runtime.Object) error {
list.Items = append(list.Items, obj)
return nil
}); err != nil {
@@ -176,26 +156,12 @@ func (p *ListPager) list(ctx context.Context, options metav1.ListOptions, allocN
//
// Items are retrieved in chunks from the server to reduce the impact on the server with up to
// ListPager.PageBufferSize chunks buffered concurrently in the background.
//
// If items passed to fn are retained for different durations, and you want to avoid
// retaining the whole slice returned by p.PageFn as long as any item is referenced,
// use EachListItemWithAlloc instead.
func (p *ListPager) EachListItem(ctx context.Context, options metav1.ListOptions, fn func(obj runtime.Object) error) error {
return p.eachListChunkBuffered(ctx, options, func(obj runtime.Object) error {
return meta.EachListItem(obj, fn)
})
}
// EachListItemWithAlloc works like EachListItem, but avoids retaining references to the items slice returned by p.PageFn.
// It does this by making a shallow copy of non-pointer items in the slice returned by p.PageFn.
//
// If the items passed to fn are not retained, or are retained for the same duration, use EachListItem instead for memory efficiency.
func (p *ListPager) EachListItemWithAlloc(ctx context.Context, options metav1.ListOptions, fn func(obj runtime.Object) error) error {
return p.eachListChunkBuffered(ctx, options, func(obj runtime.Object) error {
return meta.EachListItemWithAlloc(obj, fn)
})
}
// eachListChunkBuffered fetches runtimeObject list chunks using this ListPager and invokes fn on
// each list chunk. If fn returns an error, processing stops and that error is returned. If fn does
// not return an error, any error encountered while retrieving the list from the server is

View File

@@ -274,7 +274,7 @@ func recordEvent(sink EventSink, event *v1.Event, patch []byte, updateExistingEv
klog.Errorf("Unable to construct event '%#v': '%v' (will not retry!)", event, err)
return true
case *errors.StatusError:
if errors.IsAlreadyExists(err) || errors.HasStatusCause(err, v1.NamespaceTerminatingCause) {
if errors.IsAlreadyExists(err) {
klog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err)
} else {
klog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err)
@@ -357,9 +357,6 @@ func (recorder *recorderImpl) generateEvent(object runtime.Object, annotations m
event := recorder.makeEvent(ref, annotations, eventtype, reason, message)
event.Source = recorder.source
event.ReportingInstance = recorder.source.Host
event.ReportingController = recorder.source.Component
// NOTE: events should be a non-blocking operation, but we also need to not
// put this in a goroutine, otherwise we'll race to write to a closed channel
// when we go to shut down this broadcaster. Just drop events if we get overloaded,

View File

@@ -179,12 +179,11 @@ func TestEventf(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[2]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: false,
@@ -207,12 +206,11 @@ func TestEventf(t *testing.T) {
UID: "bar",
APIVersion: "v1",
},
Reason: "Killed",
Message: "some other verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Killed",
Message: "some other verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Killed' some other verbose message: 1`,
expectUpdate: false,
@@ -236,12 +234,11 @@ func TestEventf(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[2]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 2,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 2,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: true,
@@ -265,12 +262,11 @@ func TestEventf(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[3]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: false,
@@ -294,12 +290,11 @@ func TestEventf(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[2]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 3,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 3,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: true,
@@ -323,12 +318,11 @@ func TestEventf(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[3]",
},
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
expectUpdate: false,
@@ -352,12 +346,11 @@ func TestEventf(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[3]",
},
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 2,
Type: v1.EventTypeNormal,
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 2,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
expectUpdate: true,
@@ -742,12 +735,11 @@ func TestMultiSinkCache(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[2]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: false,
@@ -770,12 +762,11 @@ func TestMultiSinkCache(t *testing.T) {
UID: "bar",
APIVersion: "v1",
},
Reason: "Killed",
Message: "some other verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Killed",
Message: "some other verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Killed' some other verbose message: 1`,
expectUpdate: false,
@@ -799,12 +790,11 @@ func TestMultiSinkCache(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[2]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 2,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 2,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: true,
@@ -828,12 +818,11 @@ func TestMultiSinkCache(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[3]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: false,
@@ -857,12 +846,11 @@ func TestMultiSinkCache(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[2]",
},
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 3,
Type: v1.EventTypeNormal,
Reason: "Started",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 3,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
expectUpdate: true,
@@ -886,12 +874,11 @@ func TestMultiSinkCache(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[3]",
},
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 1,
Type: v1.EventTypeNormal,
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 1,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
expectUpdate: false,
@@ -915,12 +902,11 @@ func TestMultiSinkCache(t *testing.T) {
APIVersion: "v1",
FieldPath: "spec.containers[3]",
},
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
ReportingController: "eventTest",
Count: 2,
Type: v1.EventTypeNormal,
Reason: "Stopped",
Message: "some verbose message: 1",
Source: v1.EventSource{Component: "eventTest"},
Count: 2,
Type: v1.EventTypeNormal,
},
expectLog: `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"v1", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
expectUpdate: true,

View File

@@ -23,9 +23,9 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
testclocks "k8s.io/utils/clock/testing"
)
@@ -115,16 +115,13 @@ func validateEvent(messagePrefix string, actualEvent *v1.Event, expectedEvent *v
// Temp clear time stamps for comparison because actual values don't matter for comparison
recvEvent.FirstTimestamp = expectedEvent.FirstTimestamp
recvEvent.LastTimestamp = expectedEvent.LastTimestamp
recvEvent.ReportingController = expectedEvent.ReportingController
// Check that name has the right prefix.
if n, en := recvEvent.Name, expectedEvent.Name; !strings.HasPrefix(n, en) {
t.Errorf("%v - Name '%v' does not contain prefix '%v'", messagePrefix, n, en)
}
recvEvent.Name = expectedEvent.Name
if e, a := expectedEvent, &recvEvent; !reflect.DeepEqual(e, a) {
t.Errorf("%v - diff: %s", messagePrefix, cmp.Diff(e, a))
t.Errorf("%v - diff: %s", messagePrefix, diff.ObjectGoPrintDiff(e, a))
}
recvEvent.FirstTimestamp = actualFirstTimestamp
recvEvent.LastTimestamp = actualLastTimestamp

View File

@@ -17,13 +17,10 @@ limitations under the License.
package remotecommand
import (
"bytes"
"context"
"crypto/rand"
"encoding/json"
"errors"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
@@ -368,61 +365,3 @@ func TestStreamExitsAfterConnectionIsClosed(t *testing.T) {
return
}
}
func TestStreamRandomData(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
var stdin, stdout bytes.Buffer
ctx, err := createHTTPStreams(w, req, &StreamOptions{
Stdin: &stdin,
Stdout: &stdout,
})
if err != nil {
t.Errorf("error on createHTTPStreams: %v", err)
return
}
defer ctx.conn.Close()
io.Copy(ctx.stdoutStream, ctx.stdinStream)
}))
defer server.Close()
uri, _ := url.Parse(server.URL)
exec, err := NewSPDYExecutor(&rest.Config{Host: uri.Host}, "POST", uri)
if err != nil {
t.Fatal(err)
}
randomData := make([]byte, 1024*1024)
if _, err := rand.Read(randomData); err != nil {
t.Errorf("unexpected error reading random data: %v", err)
}
var stdout bytes.Buffer
options := &StreamOptions{
Stdin: bytes.NewReader(randomData),
Stdout: &stdout,
}
errorChan := make(chan error)
go func() {
errorChan <- exec.StreamWithContext(context.Background(), *options)
}()
select {
case <-time.After(wait.ForeverTestTimeout):
t.Fatalf("expect stream to be closed after connection is closed.")
case err := <-errorChan:
if err != nil {
t.Errorf("unexpected error")
}
}
data, err := ioutil.ReadAll(bytes.NewReader(stdout.Bytes()))
if err != nil {
t.Errorf("error reading the stream: %v", err)
return
}
if !bytes.Equal(randomData, data) {
t.Errorf("unexpected data received: %d sent: %d", len(data), len(randomData))
}
}

View File

@@ -24,14 +24,14 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/davecgh/go-spew/spew"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/watch"
fakeclientset "k8s.io/client-go/kubernetes/fake"
testcore "k8s.io/client-go/testing"
@@ -260,7 +260,7 @@ func TestNewInformerWatcher(t *testing.T) {
sort.Sort(byEventTypeAndName(result))
if !reflect.DeepEqual(expected, result) {
t.Errorf("\nexpected: %s,\ngot: %s,\ndiff: %s", dump.Pretty(expected), dump.Pretty(result), cmp.Diff(expected, result))
t.Error(spew.Errorf("\nexpected: %#v,\ngot: %#v,\ndiff: %s", expected, result, diff.ObjectReflectDiff(expected, result)))
return
}
@@ -302,7 +302,7 @@ func TestInformerWatcherDeletedFinalStateUnknown(t *testing.T) {
return retval, nil
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
w := watch.NewRaceFreeFake()
w := watch.NewFake()
if options.ResourceVersion == "1" {
go func() {
// Close with a "Gone" error when trying to start a watch from the first list
@@ -315,7 +315,6 @@ func TestInformerWatcherDeletedFinalStateUnknown(t *testing.T) {
},
}
_, _, w, done := NewIndexerInformerWatcher(lw, &corev1.Secret{})
defer w.Stop()
// Expect secret add
select {

View File

@@ -24,9 +24,10 @@ import (
"net/http"
"time"
"github.com/davecgh/go-spew/spew"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
@@ -190,7 +191,7 @@ func (rw *RetryWatcher) doReceive() (bool, time.Duration) {
errObject := apierrors.FromObject(event.Object)
statusErr, ok := errObject.(*apierrors.StatusError)
if !ok {
klog.Error(fmt.Sprintf("Received an error which is not *metav1.Status but %s", dump.Pretty(event.Object)))
klog.Error(spew.Sprintf("Received an error which is not *metav1.Status but %#+v", event.Object))
// Retry unknown errors
return false, 0
}
@@ -219,7 +220,7 @@ func (rw *RetryWatcher) doReceive() (bool, time.Duration) {
// Log here so we have a record of hitting the unexpected error
// and we can whitelist some error codes if we missed any that are expected.
klog.V(5).Info(fmt.Sprintf("Retrying after unexpected error: %s", dump.Pretty(event.Object)))
klog.V(5).Info(spew.Sprintf("Retrying after unexpected error: %#+v", event.Object))
// Retry
return false, statusDelay

View File

@@ -26,13 +26,13 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/davecgh/go-spew/spew"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
@@ -530,7 +530,7 @@ func TestRetryWatcher(t *testing.T) {
for i := 0; i < len(tc.expected); i++ {
event, ok := <-watcher.ResultChan()
if !ok {
t.Errorf("expected event %s, but channel is closed", dump.Pretty(tc.expected[i]))
t.Error(spew.Errorf("expected event %#+v, but channel is closed"), tc.expected[i])
break
}
@@ -544,7 +544,7 @@ func TestRetryWatcher(t *testing.T) {
select {
case event, ok := <-watcher.ResultChan():
if ok {
t.Errorf("Unexpected event received after reading all the expected ones: %s", dump.Pretty(event))
t.Error(spew.Errorf("Unexpected event received after reading all the expected ones: %#+v", event))
}
case <-time.After(10 * time.Millisecond):
break
@@ -564,7 +564,7 @@ func TestRetryWatcher(t *testing.T) {
}
if !reflect.DeepEqual(tc.expected, got) {
t.Fatalf("expected %s, got %s;\ndiff: %s", dump.Pretty(tc.expected), dump.Pretty(got), cmp.Diff(tc.expected, got))
t.Fatal(spew.Errorf("expected %#+v, got %#+v;\ndiff: %s", tc.expected, got, diff.ObjectReflectDiff(tc.expected, got)))
}
})
}

View File

@@ -27,7 +27,6 @@ import (
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/metrics"
)
// TlsTransportCache caches TLS http.RoundTrippers different configurations. The
@@ -81,16 +80,11 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
// Ensure we only create a single transport for the given TLS options
c.mu.Lock()
defer c.mu.Unlock()
defer metrics.TransportCacheEntries.Observe(len(c.transports))
// See if we already have a custom transport for this config
if t, ok := c.transports[key]; ok {
metrics.TransportCreateCalls.Increment("hit")
return t, nil
}
metrics.TransportCreateCalls.Increment("miss")
} else {
metrics.TransportCreateCalls.Increment("uncacheable")
}
// Get the TLS options for this client config

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