mirror of
https://github.com/kubernetes/client-go.git
synced 2026-06-19 16:25:23 +00:00
Compare commits
1 Commits
v0.26.0-al
...
v0.25.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e86f563ac |
1
OWNERS
1
OWNERS
@@ -9,7 +9,6 @@ approvers:
|
||||
- sttts
|
||||
- yliaog
|
||||
reviewers:
|
||||
- aojea
|
||||
- caesarxuchao
|
||||
- deads2k
|
||||
- jpbetz
|
||||
|
||||
@@ -21,7 +21,7 @@ package v1
|
||||
import (
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/client-go/applyconfigurations/core/v1"
|
||||
metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// JobSpecApplyConfiguration represents an declarative configuration of the JobSpec type for use
|
||||
@@ -30,9 +30,8 @@ type JobSpecApplyConfiguration struct {
|
||||
Parallelism *int32 `json:"parallelism,omitempty"`
|
||||
Completions *int32 `json:"completions,omitempty"`
|
||||
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
|
||||
PodFailurePolicy *PodFailurePolicyApplyConfiguration `json:"podFailurePolicy,omitempty"`
|
||||
BackoffLimit *int32 `json:"backoffLimit,omitempty"`
|
||||
Selector *metav1.LabelSelectorApplyConfiguration `json:"selector,omitempty"`
|
||||
Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"`
|
||||
ManualSelector *bool `json:"manualSelector,omitempty"`
|
||||
Template *corev1.PodTemplateSpecApplyConfiguration `json:"template,omitempty"`
|
||||
TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"`
|
||||
@@ -70,14 +69,6 @@ func (b *JobSpecApplyConfiguration) WithActiveDeadlineSeconds(value int64) *JobS
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPodFailurePolicy sets the PodFailurePolicy 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 PodFailurePolicy field is set to the value of the last call.
|
||||
func (b *JobSpecApplyConfiguration) WithPodFailurePolicy(value *PodFailurePolicyApplyConfiguration) *JobSpecApplyConfiguration {
|
||||
b.PodFailurePolicy = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithBackoffLimit sets the BackoffLimit 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 BackoffLimit field is set to the value of the last call.
|
||||
@@ -89,7 +80,7 @@ func (b *JobSpecApplyConfiguration) WithBackoffLimit(value int32) *JobSpecApplyC
|
||||
// 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 *JobSpecApplyConfiguration) WithSelector(value *metav1.LabelSelectorApplyConfiguration) *JobSpecApplyConfiguration {
|
||||
func (b *JobSpecApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *JobSpecApplyConfiguration {
|
||||
b.Selector = value
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -1,44 +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
|
||||
|
||||
// PodFailurePolicyApplyConfiguration represents an declarative configuration of the PodFailurePolicy type for use
|
||||
// with apply.
|
||||
type PodFailurePolicyApplyConfiguration struct {
|
||||
Rules []PodFailurePolicyRuleApplyConfiguration `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
// PodFailurePolicyApplyConfiguration constructs an declarative configuration of the PodFailurePolicy type for use with
|
||||
// apply.
|
||||
func PodFailurePolicy() *PodFailurePolicyApplyConfiguration {
|
||||
return &PodFailurePolicyApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithRules adds the given value to the Rules 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 Rules field.
|
||||
func (b *PodFailurePolicyApplyConfiguration) WithRules(values ...*PodFailurePolicyRuleApplyConfiguration) *PodFailurePolicyApplyConfiguration {
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithRules")
|
||||
}
|
||||
b.Rules = append(b.Rules, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
@@ -1,63 +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
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
)
|
||||
|
||||
// PodFailurePolicyOnExitCodesRequirementApplyConfiguration represents an declarative configuration of the PodFailurePolicyOnExitCodesRequirement type for use
|
||||
// with apply.
|
||||
type PodFailurePolicyOnExitCodesRequirementApplyConfiguration struct {
|
||||
ContainerName *string `json:"containerName,omitempty"`
|
||||
Operator *v1.PodFailurePolicyOnExitCodesOperator `json:"operator,omitempty"`
|
||||
Values []int32 `json:"values,omitempty"`
|
||||
}
|
||||
|
||||
// PodFailurePolicyOnExitCodesRequirementApplyConfiguration constructs an declarative configuration of the PodFailurePolicyOnExitCodesRequirement type for use with
|
||||
// apply.
|
||||
func PodFailurePolicyOnExitCodesRequirement() *PodFailurePolicyOnExitCodesRequirementApplyConfiguration {
|
||||
return &PodFailurePolicyOnExitCodesRequirementApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithContainerName sets the ContainerName 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 ContainerName field is set to the value of the last call.
|
||||
func (b *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) WithContainerName(value string) *PodFailurePolicyOnExitCodesRequirementApplyConfiguration {
|
||||
b.ContainerName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOperator sets the Operator 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 Operator field is set to the value of the last call.
|
||||
func (b *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) WithOperator(value v1.PodFailurePolicyOnExitCodesOperator) *PodFailurePolicyOnExitCodesRequirementApplyConfiguration {
|
||||
b.Operator = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithValues adds the given value to the Values 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 Values field.
|
||||
func (b *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) WithValues(values ...int32) *PodFailurePolicyOnExitCodesRequirementApplyConfiguration {
|
||||
for i := range values {
|
||||
b.Values = append(b.Values, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
@@ -1,52 +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
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// PodFailurePolicyOnPodConditionsPatternApplyConfiguration represents an declarative configuration of the PodFailurePolicyOnPodConditionsPattern type for use
|
||||
// with apply.
|
||||
type PodFailurePolicyOnPodConditionsPatternApplyConfiguration struct {
|
||||
Type *v1.PodConditionType `json:"type,omitempty"`
|
||||
Status *v1.ConditionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// PodFailurePolicyOnPodConditionsPatternApplyConfiguration constructs an declarative configuration of the PodFailurePolicyOnPodConditionsPattern type for use with
|
||||
// apply.
|
||||
func PodFailurePolicyOnPodConditionsPattern() *PodFailurePolicyOnPodConditionsPatternApplyConfiguration {
|
||||
return &PodFailurePolicyOnPodConditionsPatternApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithType sets the Type 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 Type field is set to the value of the last call.
|
||||
func (b *PodFailurePolicyOnPodConditionsPatternApplyConfiguration) WithType(value v1.PodConditionType) *PodFailurePolicyOnPodConditionsPatternApplyConfiguration {
|
||||
b.Type = &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 *PodFailurePolicyOnPodConditionsPatternApplyConfiguration) WithStatus(value v1.ConditionStatus) *PodFailurePolicyOnPodConditionsPatternApplyConfiguration {
|
||||
b.Status = &value
|
||||
return b
|
||||
}
|
||||
@@ -1,66 +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
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
)
|
||||
|
||||
// PodFailurePolicyRuleApplyConfiguration represents an declarative configuration of the PodFailurePolicyRule type for use
|
||||
// with apply.
|
||||
type PodFailurePolicyRuleApplyConfiguration struct {
|
||||
Action *v1.PodFailurePolicyAction `json:"action,omitempty"`
|
||||
OnExitCodes *PodFailurePolicyOnExitCodesRequirementApplyConfiguration `json:"onExitCodes,omitempty"`
|
||||
OnPodConditions []PodFailurePolicyOnPodConditionsPatternApplyConfiguration `json:"onPodConditions,omitempty"`
|
||||
}
|
||||
|
||||
// PodFailurePolicyRuleApplyConfiguration constructs an declarative configuration of the PodFailurePolicyRule type for use with
|
||||
// apply.
|
||||
func PodFailurePolicyRule() *PodFailurePolicyRuleApplyConfiguration {
|
||||
return &PodFailurePolicyRuleApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithAction sets the Action 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 Action field is set to the value of the last call.
|
||||
func (b *PodFailurePolicyRuleApplyConfiguration) WithAction(value v1.PodFailurePolicyAction) *PodFailurePolicyRuleApplyConfiguration {
|
||||
b.Action = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOnExitCodes sets the OnExitCodes 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 OnExitCodes field is set to the value of the last call.
|
||||
func (b *PodFailurePolicyRuleApplyConfiguration) WithOnExitCodes(value *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) *PodFailurePolicyRuleApplyConfiguration {
|
||||
b.OnExitCodes = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOnPodConditions adds the given value to the OnPodConditions 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 OnPodConditions field.
|
||||
func (b *PodFailurePolicyRuleApplyConfiguration) WithOnPodConditions(values ...*PodFailurePolicyOnPodConditionsPatternApplyConfiguration) *PodFailurePolicyRuleApplyConfiguration {
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOnPodConditions")
|
||||
}
|
||||
b.OnPodConditions = append(b.OnPodConditions, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
@@ -3041,9 +3041,6 @@ var schemaYAML = typed.YAMLObject(`types:
|
||||
- name: parallelism
|
||||
type:
|
||||
scalar: numeric
|
||||
- name: podFailurePolicy
|
||||
type:
|
||||
namedType: io.k8s.api.batch.v1.PodFailurePolicy
|
||||
- name: selector
|
||||
type:
|
||||
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector
|
||||
@@ -3101,58 +3098,6 @@ var schemaYAML = typed.YAMLObject(`types:
|
||||
type:
|
||||
namedType: io.k8s.api.batch.v1.JobSpec
|
||||
default: {}
|
||||
- name: io.k8s.api.batch.v1.PodFailurePolicy
|
||||
map:
|
||||
fields:
|
||||
- name: rules
|
||||
type:
|
||||
list:
|
||||
elementType:
|
||||
namedType: io.k8s.api.batch.v1.PodFailurePolicyRule
|
||||
elementRelationship: atomic
|
||||
- name: io.k8s.api.batch.v1.PodFailurePolicyOnExitCodesRequirement
|
||||
map:
|
||||
fields:
|
||||
- name: containerName
|
||||
type:
|
||||
scalar: string
|
||||
- name: operator
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: values
|
||||
type:
|
||||
list:
|
||||
elementType:
|
||||
scalar: numeric
|
||||
elementRelationship: associative
|
||||
- name: io.k8s.api.batch.v1.PodFailurePolicyOnPodConditionsPattern
|
||||
map:
|
||||
fields:
|
||||
- name: status
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: type
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: io.k8s.api.batch.v1.PodFailurePolicyRule
|
||||
map:
|
||||
fields:
|
||||
- name: action
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: onExitCodes
|
||||
type:
|
||||
namedType: io.k8s.api.batch.v1.PodFailurePolicyOnExitCodesRequirement
|
||||
- name: onPodConditions
|
||||
type:
|
||||
list:
|
||||
elementType:
|
||||
namedType: io.k8s.api.batch.v1.PodFailurePolicyOnPodConditionsPattern
|
||||
elementRelationship: atomic
|
||||
- name: io.k8s.api.batch.v1.UncountedTerminatedPods
|
||||
map:
|
||||
fields:
|
||||
@@ -9593,41 +9538,6 @@ var schemaYAML = typed.YAMLObject(`types:
|
||||
- name: number
|
||||
type:
|
||||
scalar: numeric
|
||||
- name: io.k8s.api.networking.v1alpha1.ClusterCIDR
|
||||
map:
|
||||
fields:
|
||||
- name: apiVersion
|
||||
type:
|
||||
scalar: string
|
||||
- name: kind
|
||||
type:
|
||||
scalar: string
|
||||
- name: metadata
|
||||
type:
|
||||
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
|
||||
default: {}
|
||||
- name: spec
|
||||
type:
|
||||
namedType: io.k8s.api.networking.v1alpha1.ClusterCIDRSpec
|
||||
default: {}
|
||||
- name: io.k8s.api.networking.v1alpha1.ClusterCIDRSpec
|
||||
map:
|
||||
fields:
|
||||
- name: ipv4
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: ipv6
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: nodeSelector
|
||||
type:
|
||||
namedType: io.k8s.api.core.v1.NodeSelector
|
||||
- name: perNodeHostBits
|
||||
type:
|
||||
scalar: numeric
|
||||
default: 0
|
||||
- name: io.k8s.api.networking.v1beta1.HTTPIngressPath
|
||||
map:
|
||||
fields:
|
||||
|
||||
@@ -1,66 +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
|
||||
|
||||
// ListMetaApplyConfiguration represents an declarative configuration of the ListMeta type for use
|
||||
// with apply.
|
||||
type ListMetaApplyConfiguration struct {
|
||||
SelfLink *string `json:"selfLink,omitempty"`
|
||||
ResourceVersion *string `json:"resourceVersion,omitempty"`
|
||||
Continue *string `json:"continue,omitempty"`
|
||||
RemainingItemCount *int64 `json:"remainingItemCount,omitempty"`
|
||||
}
|
||||
|
||||
// ListMetaApplyConfiguration constructs an declarative configuration of the ListMeta type for use with
|
||||
// apply.
|
||||
func ListMeta() *ListMetaApplyConfiguration {
|
||||
return &ListMetaApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithSelfLink sets the SelfLink 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 SelfLink field is set to the value of the last call.
|
||||
func (b *ListMetaApplyConfiguration) WithSelfLink(value string) *ListMetaApplyConfiguration {
|
||||
b.SelfLink = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion 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 ResourceVersion field is set to the value of the last call.
|
||||
func (b *ListMetaApplyConfiguration) WithResourceVersion(value string) *ListMetaApplyConfiguration {
|
||||
b.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithContinue sets the Continue 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 Continue field is set to the value of the last call.
|
||||
func (b *ListMetaApplyConfiguration) WithContinue(value string) *ListMetaApplyConfiguration {
|
||||
b.Continue = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithRemainingItemCount sets the RemainingItemCount 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 RemainingItemCount field is set to the value of the last call.
|
||||
func (b *ListMetaApplyConfiguration) WithRemainingItemCount(value int64) *ListMetaApplyConfiguration {
|
||||
b.RemainingItemCount = &value
|
||||
return b
|
||||
}
|
||||
@@ -1,247 +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
|
||||
|
||||
import (
|
||||
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
managedfields "k8s.io/apimachinery/pkg/util/managedfields"
|
||||
internal "k8s.io/client-go/applyconfigurations/internal"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// ClusterCIDRApplyConfiguration represents an declarative configuration of the ClusterCIDR type for use
|
||||
// with apply.
|
||||
type ClusterCIDRApplyConfiguration struct {
|
||||
v1.TypeMetaApplyConfiguration `json:",inline"`
|
||||
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||
Spec *ClusterCIDRSpecApplyConfiguration `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterCIDR constructs an declarative configuration of the ClusterCIDR type for use with
|
||||
// apply.
|
||||
func ClusterCIDR(name string) *ClusterCIDRApplyConfiguration {
|
||||
b := &ClusterCIDRApplyConfiguration{}
|
||||
b.WithName(name)
|
||||
b.WithKind("ClusterCIDR")
|
||||
b.WithAPIVersion("networking.k8s.io/v1alpha1")
|
||||
return b
|
||||
}
|
||||
|
||||
// ExtractClusterCIDR extracts the applied configuration owned by fieldManager from
|
||||
// clusterCIDR. If no managedFields are found in clusterCIDR for fieldManager, a
|
||||
// ClusterCIDRApplyConfiguration is returned with only the Name, Namespace (if applicable),
|
||||
// APIVersion and Kind populated. It is possible that no managed fields were found for because other
|
||||
// field managers have taken ownership of all the fields previously owned by fieldManager, or because
|
||||
// the fieldManager never owned fields any fields.
|
||||
// clusterCIDR must be a unmodified ClusterCIDR API object that was retrieved from the Kubernetes API.
|
||||
// ExtractClusterCIDR provides a way to perform a extract/modify-in-place/apply workflow.
|
||||
// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously
|
||||
// applied if another fieldManager has updated or force applied any of the previously applied fields.
|
||||
// Experimental!
|
||||
func ExtractClusterCIDR(clusterCIDR *networkingv1alpha1.ClusterCIDR, fieldManager string) (*ClusterCIDRApplyConfiguration, error) {
|
||||
return extractClusterCIDR(clusterCIDR, fieldManager, "")
|
||||
}
|
||||
|
||||
// ExtractClusterCIDRStatus is the same as ExtractClusterCIDR except
|
||||
// that it extracts the status subresource applied configuration.
|
||||
// Experimental!
|
||||
func ExtractClusterCIDRStatus(clusterCIDR *networkingv1alpha1.ClusterCIDR, fieldManager string) (*ClusterCIDRApplyConfiguration, error) {
|
||||
return extractClusterCIDR(clusterCIDR, fieldManager, "status")
|
||||
}
|
||||
|
||||
func extractClusterCIDR(clusterCIDR *networkingv1alpha1.ClusterCIDR, fieldManager string, subresource string) (*ClusterCIDRApplyConfiguration, error) {
|
||||
b := &ClusterCIDRApplyConfiguration{}
|
||||
err := managedfields.ExtractInto(clusterCIDR, internal.Parser().Type("io.k8s.api.networking.v1alpha1.ClusterCIDR"), fieldManager, b, subresource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.WithName(clusterCIDR.Name)
|
||||
|
||||
b.WithKind("ClusterCIDR")
|
||||
b.WithAPIVersion("networking.k8s.io/v1alpha1")
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// WithKind sets the Kind 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 Kind field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithKind(value string) *ClusterCIDRApplyConfiguration {
|
||||
b.Kind = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAPIVersion sets the APIVersion 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 APIVersion field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithAPIVersion(value string) *ClusterCIDRApplyConfiguration {
|
||||
b.APIVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// 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 *ClusterCIDRApplyConfiguration) WithName(value string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateName sets the GenerateName 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 GenerateName field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithGenerateName(value string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.GenerateName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithNamespace sets the Namespace 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 Namespace field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithNamespace(value string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.Namespace = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUID sets the UID 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 UID field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithUID(value types.UID) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.UID = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion 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 ResourceVersion field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithResourceVersion(value string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGeneration sets the Generation 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 Generation field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithGeneration(value int64) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.Generation = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithCreationTimestamp sets the CreationTimestamp 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 CreationTimestamp field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.CreationTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionTimestamp sets the DeletionTimestamp 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 DeletionTimestamp field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.DeletionTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds 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 DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.DeletionGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithLabels puts the entries into the Labels 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 Labels field,
|
||||
// overwriting an existing map entries in Labels field with the same key.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithLabels(entries map[string]string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.Labels == nil && len(entries) > 0 {
|
||||
b.Labels = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.Labels[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAnnotations puts the entries into the Annotations 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 Annotations field,
|
||||
// overwriting an existing map entries in Annotations field with the same key.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.Annotations == nil && len(entries) > 0 {
|
||||
b.Annotations = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.Annotations[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOwnerReferences adds the given value to the OwnerReferences 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 OwnerReferences field.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOwnerReferences")
|
||||
}
|
||||
b.OwnerReferences = append(b.OwnerReferences, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFinalizers adds the given value to the Finalizers 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 Finalizers field.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithFinalizers(values ...string) *ClusterCIDRApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
b.Finalizers = append(b.Finalizers, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *ClusterCIDRApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||
if b.ObjectMetaApplyConfiguration == nil {
|
||||
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the Spec 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 Spec field is set to the value of the last call.
|
||||
func (b *ClusterCIDRApplyConfiguration) WithSpec(value *ClusterCIDRSpecApplyConfiguration) *ClusterCIDRApplyConfiguration {
|
||||
b.Spec = value
|
||||
return b
|
||||
}
|
||||
@@ -1,70 +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
|
||||
|
||||
import (
|
||||
v1 "k8s.io/client-go/applyconfigurations/core/v1"
|
||||
)
|
||||
|
||||
// ClusterCIDRSpecApplyConfiguration represents an declarative configuration of the ClusterCIDRSpec type for use
|
||||
// with apply.
|
||||
type ClusterCIDRSpecApplyConfiguration struct {
|
||||
NodeSelector *v1.NodeSelectorApplyConfiguration `json:"nodeSelector,omitempty"`
|
||||
PerNodeHostBits *int32 `json:"perNodeHostBits,omitempty"`
|
||||
IPv4 *string `json:"ipv4,omitempty"`
|
||||
IPv6 *string `json:"ipv6,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterCIDRSpecApplyConfiguration constructs an declarative configuration of the ClusterCIDRSpec type for use with
|
||||
// apply.
|
||||
func ClusterCIDRSpec() *ClusterCIDRSpecApplyConfiguration {
|
||||
return &ClusterCIDRSpecApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithNodeSelector sets the NodeSelector 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 NodeSelector field is set to the value of the last call.
|
||||
func (b *ClusterCIDRSpecApplyConfiguration) WithNodeSelector(value *v1.NodeSelectorApplyConfiguration) *ClusterCIDRSpecApplyConfiguration {
|
||||
b.NodeSelector = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPerNodeHostBits sets the PerNodeHostBits 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 PerNodeHostBits field is set to the value of the last call.
|
||||
func (b *ClusterCIDRSpecApplyConfiguration) WithPerNodeHostBits(value int32) *ClusterCIDRSpecApplyConfiguration {
|
||||
b.PerNodeHostBits = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithIPv4 sets the IPv4 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 IPv4 field is set to the value of the last call.
|
||||
func (b *ClusterCIDRSpecApplyConfiguration) WithIPv4(value string) *ClusterCIDRSpecApplyConfiguration {
|
||||
b.IPv4 = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithIPv6 sets the IPv6 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 IPv6 field is set to the value of the last call.
|
||||
func (b *ClusterCIDRSpecApplyConfiguration) WithIPv6(value string) *ClusterCIDRSpecApplyConfiguration {
|
||||
b.IPv6 = &value
|
||||
return b
|
||||
}
|
||||
@@ -46,7 +46,6 @@ import (
|
||||
flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2"
|
||||
imagepolicyv1alpha1 "k8s.io/api/imagepolicy/v1alpha1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -92,7 +91,6 @@ import (
|
||||
applyconfigurationsimagepolicyv1alpha1 "k8s.io/client-go/applyconfigurations/imagepolicy/v1alpha1"
|
||||
applyconfigurationsmetav1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
applyconfigurationsnetworkingv1 "k8s.io/client-go/applyconfigurations/networking/v1"
|
||||
applyconfigurationsnetworkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1"
|
||||
applyconfigurationsnetworkingv1beta1 "k8s.io/client-go/applyconfigurations/networking/v1beta1"
|
||||
applyconfigurationsnodev1 "k8s.io/client-go/applyconfigurations/node/v1"
|
||||
applyconfigurationsnodev1alpha1 "k8s.io/client-go/applyconfigurations/node/v1alpha1"
|
||||
@@ -449,14 +447,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
return &applyconfigurationsbatchv1.JobStatusApplyConfiguration{}
|
||||
case batchv1.SchemeGroupVersion.WithKind("JobTemplateSpec"):
|
||||
return &applyconfigurationsbatchv1.JobTemplateSpecApplyConfiguration{}
|
||||
case batchv1.SchemeGroupVersion.WithKind("PodFailurePolicy"):
|
||||
return &applyconfigurationsbatchv1.PodFailurePolicyApplyConfiguration{}
|
||||
case batchv1.SchemeGroupVersion.WithKind("PodFailurePolicyOnExitCodesRequirement"):
|
||||
return &applyconfigurationsbatchv1.PodFailurePolicyOnExitCodesRequirementApplyConfiguration{}
|
||||
case batchv1.SchemeGroupVersion.WithKind("PodFailurePolicyOnPodConditionsPattern"):
|
||||
return &applyconfigurationsbatchv1.PodFailurePolicyOnPodConditionsPatternApplyConfiguration{}
|
||||
case batchv1.SchemeGroupVersion.WithKind("PodFailurePolicyRule"):
|
||||
return &applyconfigurationsbatchv1.PodFailurePolicyRuleApplyConfiguration{}
|
||||
case batchv1.SchemeGroupVersion.WithKind("UncountedTerminatedPods"):
|
||||
return &applyconfigurationsbatchv1.UncountedTerminatedPodsApplyConfiguration{}
|
||||
|
||||
@@ -1208,12 +1198,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
case networkingv1.SchemeGroupVersion.WithKind("ServiceBackendPort"):
|
||||
return &applyconfigurationsnetworkingv1.ServiceBackendPortApplyConfiguration{}
|
||||
|
||||
// Group=networking.k8s.io, Version=v1alpha1
|
||||
case networkingv1alpha1.SchemeGroupVersion.WithKind("ClusterCIDR"):
|
||||
return &applyconfigurationsnetworkingv1alpha1.ClusterCIDRApplyConfiguration{}
|
||||
case networkingv1alpha1.SchemeGroupVersion.WithKind("ClusterCIDRSpec"):
|
||||
return &applyconfigurationsnetworkingv1alpha1.ClusterCIDRSpecApplyConfiguration{}
|
||||
|
||||
// Group=networking.k8s.io, Version=v1beta1
|
||||
case networkingv1beta1.SchemeGroupVersion.WithKind("HTTPIngressPath"):
|
||||
return &applyconfigurationsnetworkingv1beta1.HTTPIngressPathApplyConfiguration{}
|
||||
|
||||
@@ -18,7 +18,7 @@ package disk
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -157,7 +157,7 @@ func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) {
|
||||
}
|
||||
|
||||
// the cache is present and its valid. Try to read and use it.
|
||||
cachedBytes, err := io.ReadAll(file)
|
||||
cachedBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -179,7 +179,7 @@ func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Obj
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)+".")
|
||||
f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package disk
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -41,7 +42,7 @@ import (
|
||||
func TestCachedDiscoveryClient_Fresh(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
d, err := os.MkdirTemp("", "")
|
||||
d, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(d)
|
||||
|
||||
@@ -85,7 +86,7 @@ func TestCachedDiscoveryClient_Fresh(t *testing.T) {
|
||||
func TestNewCachedDiscoveryClient_TTL(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
d, err := os.MkdirTemp("", "")
|
||||
d, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(d)
|
||||
|
||||
@@ -103,7 +104,7 @@ func TestNewCachedDiscoveryClient_TTL(t *testing.T) {
|
||||
func TestNewCachedDiscoveryClient_PathPerm(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
d, err := os.MkdirTemp("", "")
|
||||
d, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
os.RemoveAll(d)
|
||||
defer os.RemoveAll(d)
|
||||
@@ -130,13 +131,13 @@ func TestNewCachedDiscoveryClient_PathPerm(t *testing.T) {
|
||||
// successive calls
|
||||
func TestOpenAPIDiskCache(t *testing.T) {
|
||||
// Create discovery cache dir (unused)
|
||||
discoCache, err := os.MkdirTemp("", "")
|
||||
discoCache, err := ioutil.TempDir("", "")
|
||||
require.NoError(t, err)
|
||||
os.RemoveAll(discoCache)
|
||||
defer os.RemoveAll(discoCache)
|
||||
|
||||
// Create http cache dir
|
||||
httpCache, err := os.MkdirTemp("", "")
|
||||
httpCache, err := ioutil.TempDir("", "")
|
||||
require.NoError(t, err)
|
||||
os.RemoveAll(httpCache)
|
||||
defer os.RemoveAll(httpCache)
|
||||
|
||||
@@ -19,7 +19,7 @@ package disk
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -43,7 +43,7 @@ func (rt *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
func BenchmarkDiskCache(b *testing.B) {
|
||||
cacheDir, err := os.MkdirTemp("", "cache-rt")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-rt")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func BenchmarkDiskCache(b *testing.B) {
|
||||
})
|
||||
|
||||
k := "localhost:8080/apis/batch/v1.json"
|
||||
v, err := os.ReadFile("../../testdata/apis/batch/v1.json")
|
||||
v, err := ioutil.ReadFile("../../testdata/apis/batch/v1.json")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func BenchmarkDiskCache(b *testing.B) {
|
||||
|
||||
func TestCacheRoundTripper(t *testing.T) {
|
||||
rt := &testRoundTripper{}
|
||||
cacheDir, err := os.MkdirTemp("", "cache-rt")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-rt")
|
||||
defer os.RemoveAll(cacheDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -87,14 +87,14 @@ func TestCacheRoundTripper(t *testing.T) {
|
||||
}
|
||||
rt.Response = &http.Response{
|
||||
Header: http.Header{"ETag": []string{`"123456"`}},
|
||||
Body: io.NopCloser(bytes.NewReader([]byte("Content"))),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Content"))),
|
||||
StatusCode: http.StatusOK,
|
||||
}
|
||||
resp, err := cache.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func TestCacheRoundTripper(t *testing.T) {
|
||||
}
|
||||
rt.Response = &http.Response{
|
||||
StatusCode: http.StatusNotModified,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte("Other Content"))),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Other Content"))),
|
||||
}
|
||||
|
||||
resp, err = cache.RoundTrip(req)
|
||||
@@ -118,7 +118,7 @@ func TestCacheRoundTripper(t *testing.T) {
|
||||
}
|
||||
|
||||
// Read body and make sure we have the initial content
|
||||
content, err = io.ReadAll(resp.Body)
|
||||
content, err = ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -132,7 +132,7 @@ func TestCacheRoundTripperPathPerm(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
rt := &testRoundTripper{}
|
||||
cacheDir, err := os.MkdirTemp("", "cache-rt")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-rt")
|
||||
os.RemoveAll(cacheDir)
|
||||
defer os.RemoveAll(cacheDir)
|
||||
|
||||
@@ -148,14 +148,14 @@ func TestCacheRoundTripperPathPerm(t *testing.T) {
|
||||
}
|
||||
rt.Response = &http.Response{
|
||||
Header: http.Header{"ETag": []string{`"123456"`}},
|
||||
Body: io.NopCloser(bytes.NewReader([]byte("Content"))),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Content"))),
|
||||
StatusCode: http.StatusOK,
|
||||
}
|
||||
resp, err := cache.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -182,7 +182,7 @@ func TestSumDiskCache(t *testing.T) {
|
||||
|
||||
// Ensure that we'll return a cache miss if the backing file doesn't exist.
|
||||
t.Run("NoSuchKey", func(t *testing.T) {
|
||||
cacheDir, err := os.MkdirTemp("", "cache-test")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func TestSumDiskCache(t *testing.T) {
|
||||
|
||||
// Ensure that we'll return a cache miss if the backing file is empty.
|
||||
t.Run("EmptyFile", func(t *testing.T) {
|
||||
cacheDir, err := os.MkdirTemp("", "cache-test")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -223,7 +223,7 @@ func TestSumDiskCache(t *testing.T) {
|
||||
// Ensure that we'll return a cache miss if the backing has an invalid
|
||||
// checksum.
|
||||
t.Run("InvalidChecksum", func(t *testing.T) {
|
||||
cacheDir, err := os.MkdirTemp("", "cache-test")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -258,7 +258,7 @@ func TestSumDiskCache(t *testing.T) {
|
||||
// This should cause httpcache to fall back to its underlying transport and
|
||||
// to subsequently cache the new value, overwriting the corrupt one.
|
||||
t.Run("OverwriteExistingKey", func(t *testing.T) {
|
||||
cacheDir, err := os.MkdirTemp("", "cache-test")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -290,7 +290,7 @@ func TestSumDiskCache(t *testing.T) {
|
||||
|
||||
// Ensure that deleting a key does in fact delete it.
|
||||
t.Run("DeleteKey", func(t *testing.T) {
|
||||
cacheDir, err := os.MkdirTemp("", "cache-test")
|
||||
cacheDir, err := ioutil.TempDir("", "cache-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -40,7 +41,7 @@ func objBody(object interface{}) io.ReadCloser {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return io.NopCloser(bytes.NewReader([]byte(output)))
|
||||
return ioutil.NopCloser(bytes.NewReader([]byte(output)))
|
||||
}
|
||||
|
||||
func TestServerSupportsVersion(t *testing.T) {
|
||||
|
||||
@@ -20,11 +20,10 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -406,7 +405,7 @@ func TestCreate(t *testing.T) {
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
data, err := io.ReadAll(r.Body)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Create(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
@@ -488,7 +487,7 @@ func TestUpdate(t *testing.T) {
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
data, err := io.ReadAll(r.Body)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Update(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
@@ -646,7 +645,7 @@ func TestPatch(t *testing.T) {
|
||||
t.Errorf("Patch(%q) got Content-Type %s. wanted %s", tc.name, content, types.StrategicMergePatchType)
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(r.Body)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Patch(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
@@ -673,107 +672,3 @@ func TestPatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidSegments(t *testing.T) {
|
||||
name := "bad/name"
|
||||
namespace := "bad/namespace"
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||
obj := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "vtest",
|
||||
"kind": "vkind",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name,
|
||||
},
|
||||
},
|
||||
}
|
||||
cl, err := NewForConfig(&restclient.Config{
|
||||
Host: "127.0.0.1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create config: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Namespace(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Update(context.TODO(), obj, metav1.UpdateOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
_, err = cl.Resource(resource).Namespace(namespace).Update(context.TODO(), obj, metav1.UpdateOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).UpdateStatus(context.TODO(), obj, metav1.UpdateOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
_, err = cl.Resource(resource).Namespace(namespace).UpdateStatus(context.TODO(), obj, metav1.UpdateOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
err = cl.Resource(resource).Delete(context.TODO(), name, metav1.DeleteOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
err = cl.Resource(resource).Namespace(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
err = cl.Resource(resource).Namespace(namespace).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
_, err = cl.Resource(resource).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Namespace(namespace).List(context.TODO(), metav1.ListOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Namespace(namespace).Watch(context.TODO(), metav1.ListOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Patch(context.TODO(), name, types.StrategicMergePatchType, []byte("{}"), metav1.PatchOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
_, err = cl.Resource(resource).Namespace(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, []byte("{}"), metav1.PatchOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).Apply(context.TODO(), name, obj, metav1.ApplyOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
_, err = cl.Resource(resource).Namespace(namespace).Apply(context.TODO(), name, obj, metav1.ApplyOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
|
||||
_, err = cl.Resource(resource).ApplyStatus(context.TODO(), name, obj, metav1.ApplyOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid resource name") {
|
||||
t.Fatalf("Expected `invalid resource name` error, got: %v", err)
|
||||
}
|
||||
_, err = cl.Resource(resource).Namespace(namespace).ApplyStatus(context.TODO(), name, obj, metav1.ApplyOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid namespace") {
|
||||
t.Fatalf("Expected `invalid namespace` error, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,9 +120,6 @@ func (c *dynamicResourceClient) Create(ctx context.Context, obj *unstructured.Un
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Post().
|
||||
@@ -155,9 +152,6 @@ func (c *dynamicResourceClient) Update(ctx context.Context, obj *unstructured.Un
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -194,9 +188,7 @@ func (c *dynamicResourceClient) UpdateStatus(ctx context.Context, obj *unstructu
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -228,9 +220,6 @@ func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts me
|
||||
if len(name) == 0 {
|
||||
return fmt.Errorf("name is required")
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return err
|
||||
}
|
||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -246,10 +235,6 @@ func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts me
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
if err := validateNamespaceWithOptionalName(c.namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -269,9 +254,6 @@ func (c *dynamicResourceClient) Get(ctx context.Context, name string, opts metav
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := c.client.client.Get().AbsPath(append(c.makeURLSegments(name), subresources...)...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
@@ -288,9 +270,6 @@ func (c *dynamicResourceClient) Get(ctx context.Context, name string, opts metav
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||
if err := validateNamespaceWithOptionalName(c.namespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := c.client.client.Get().AbsPath(c.makeURLSegments("")...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
@@ -316,9 +295,6 @@ func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOption
|
||||
|
||||
func (c *dynamicResourceClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
|
||||
opts.Watch = true
|
||||
if err := validateNamespaceWithOptionalName(c.namespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.client.client.Get().AbsPath(c.makeURLSegments("")...).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Watch(ctx)
|
||||
@@ -328,9 +304,6 @@ func (c *dynamicResourceClient) Patch(ctx context.Context, name string, pt types
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := c.client.client.
|
||||
Patch(pt).
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
@@ -355,9 +328,6 @@ func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *uns
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -396,20 +366,6 @@ func (c *dynamicResourceClient) ApplyStatus(ctx context.Context, name string, ob
|
||||
return c.Apply(ctx, name, obj, opts, "status")
|
||||
}
|
||||
|
||||
func validateNamespaceWithOptionalName(namespace string, name ...string) error {
|
||||
if msgs := rest.IsValidPathSegmentName(namespace); len(msgs) != 0 {
|
||||
return fmt.Errorf("invalid namespace %q: %v", namespace, msgs)
|
||||
}
|
||||
if len(name) > 1 {
|
||||
panic("Invalid number of names")
|
||||
} else if len(name) == 1 {
|
||||
if msgs := rest.IsValidPathSegmentName(name[0]); len(msgs) != 0 {
|
||||
return fmt.Errorf("invalid resource name %q: %v", name[0], msgs)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) makeURLSegments(name string) []string {
|
||||
url := []string{}
|
||||
if len(c.resource.Group) == 0 {
|
||||
|
||||
@@ -19,6 +19,7 @@ Or you can load specific auth plugins:
|
||||
import _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
import _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
import _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
import _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
```
|
||||
|
||||
### Configuration
|
||||
@@ -37,7 +38,7 @@ import _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
|
||||
- [**Work queues**](./workqueue): Create a hotloop-free controller with the
|
||||
rate-limited workqueue and the [informer framework][informer].
|
||||
- [**Custom Resource Definition (CRD)**](https://git.k8s.io/apiextensions-apiserver/examples/client-go):
|
||||
- [**Custom Resource Definition (successor of TPR)**](https://git.k8s.io/apiextensions-apiserver/examples/client-go):
|
||||
Register a custom resource type with the API, create/update/query this custom
|
||||
type, and write a controller that drives the cluster state based on the changes to
|
||||
the custom resources.
|
||||
|
||||
@@ -40,6 +40,7 @@ import (
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -52,6 +53,8 @@ func main() {
|
||||
}
|
||||
flag.Parse()
|
||||
|
||||
namespace := "default"
|
||||
|
||||
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -106,7 +109,7 @@ func main() {
|
||||
|
||||
// Create Deployment
|
||||
fmt.Println("Creating deployment...")
|
||||
result, err := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Create(context.TODO(), deployment, metav1.CreateOptions{})
|
||||
result, err := client.Resource(deploymentRes).Namespace(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -131,7 +134,7 @@ func main() {
|
||||
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
// Retrieve the latest version of Deployment before attempting update
|
||||
// RetryOnConflict uses exponential backoff to avoid exhausting the apiserver
|
||||
result, getErr := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
|
||||
result, getErr := client.Resource(deploymentRes).Namespace(namespace).Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
|
||||
if getErr != nil {
|
||||
panic(fmt.Errorf("failed to get latest version of Deployment: %v", getErr))
|
||||
}
|
||||
@@ -155,7 +158,7 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, updateErr := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Update(context.TODO(), result, metav1.UpdateOptions{})
|
||||
_, updateErr := client.Resource(deploymentRes).Namespace(namespace).Update(context.TODO(), result, metav1.UpdateOptions{})
|
||||
return updateErr
|
||||
})
|
||||
if retryErr != nil {
|
||||
@@ -166,7 +169,7 @@ func main() {
|
||||
// List Deployments
|
||||
prompt()
|
||||
fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
|
||||
list, err := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).List(context.TODO(), metav1.ListOptions{})
|
||||
list, err := client.Resource(deploymentRes).Namespace(namespace).List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -186,7 +189,7 @@ func main() {
|
||||
deleteOptions := metav1.DeleteOptions{
|
||||
PropagationPolicy: &deletePolicy,
|
||||
}
|
||||
if err := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Delete(context.TODO(), "demo-deployment", deleteOptions); err != nil {
|
||||
if err := client.Resource(deploymentRes).Namespace(namespace).Delete(context.TODO(), "demo-deployment", deleteOptions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
20
go.mod
20
go.mod
@@ -11,22 +11,22 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/gnostic v0.5.7-v3refs
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/go-cmp v0.5.6
|
||||
github.com/google/gofuzz v1.1.0
|
||||
github.com/google/uuid v1.1.2
|
||||
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.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
|
||||
google.golang.org/protobuf v1.28.1
|
||||
k8s.io/api v0.26.0-alpha.1
|
||||
k8s.io/apimachinery v0.26.0-alpha.1
|
||||
k8s.io/klog/v2 v2.80.1
|
||||
google.golang.org/protobuf v1.28.0
|
||||
k8s.io/api v0.25.0-beta.0
|
||||
k8s.io/apimachinery v0.25.0-beta.0
|
||||
k8s.io/klog/v2 v2.70.1
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3
|
||||
@@ -36,7 +36,7 @@ require (
|
||||
require (
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
||||
@@ -61,6 +61,6 @@ require (
|
||||
)
|
||||
|
||||
replace (
|
||||
k8s.io/api => k8s.io/api v0.26.0-alpha.1
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.26.0-alpha.1
|
||||
k8s.io/api => k8s.io/api v0.25.0-beta.0
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.25.0-beta.0
|
||||
)
|
||||
|
||||
42
go.sum
42
go.sum
@@ -50,8 +50,8 @@ 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/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
|
||||
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/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
|
||||
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
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=
|
||||
@@ -118,8 +118,8 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
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/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.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=
|
||||
@@ -174,8 +174,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
||||
github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
|
||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
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=
|
||||
@@ -189,14 +189,12 @@ 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/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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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=
|
||||
@@ -269,7 +267,6 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
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.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -277,8 +274,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
|
||||
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/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
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=
|
||||
@@ -314,8 +311,6 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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.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.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
@@ -377,6 +372,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
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=
|
||||
@@ -456,8 +452,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/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=
|
||||
@@ -481,13 +477,13 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
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.26.0-alpha.1 h1:0uaX04eLS9dwIcuWgRvu+WoB63hXFdc9s8fSeR6C1PI=
|
||||
k8s.io/api v0.26.0-alpha.1/go.mod h1:snuTxVDYyZ0s0Ftc/3Cvl8jZ9zLPDn7PQliEqn93Rrs=
|
||||
k8s.io/apimachinery v0.26.0-alpha.1 h1:9ZD9i3tISdlxc18MpS3SGc3Hlsyqtkf8/FeRucTfUTI=
|
||||
k8s.io/apimachinery v0.26.0-alpha.1/go.mod h1:YxcSfgHt+jqvurbA0MLOvpo1OlrnkzW3sZTxMu+hrgI=
|
||||
k8s.io/api v0.25.0-beta.0 h1:7gOhPDIb64uxBn9IADZDU2Kz3R7/HzYGMOQ4REsz6rE=
|
||||
k8s.io/api v0.25.0-beta.0/go.mod h1:N4fOjxA9rFu2Trkid57zYj46pZjtumuyuhDaq30UquA=
|
||||
k8s.io/apimachinery v0.25.0-beta.0 h1:D+AORv53PNNqTb98A0MgWonJP4bTPpWXfNDLWM++0ro=
|
||||
k8s.io/apimachinery v0.25.0-beta.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
|
||||
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA=
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
|
||||
|
||||
@@ -64,11 +64,6 @@ type sharedInformerFactory struct {
|
||||
// startedInformers is used for tracking which informers have been started.
|
||||
// This allows Start() to be called multiple times safely.
|
||||
startedInformers map[reflect.Type]bool
|
||||
// wg tracks how many goroutines were started.
|
||||
wg sync.WaitGroup
|
||||
// shuttingDown is true when Shutdown has been called. It may still be running
|
||||
// because it needs to wait for goroutines.
|
||||
shuttingDown bool
|
||||
}
|
||||
|
||||
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
|
||||
@@ -129,39 +124,20 @@ func NewSharedInformerFactoryWithOptions(client kubernetes.Interface, defaultRes
|
||||
return factory
|
||||
}
|
||||
|
||||
// Start initializes all requested informers.
|
||||
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
if f.shuttingDown {
|
||||
return
|
||||
}
|
||||
|
||||
for informerType, informer := range f.informers {
|
||||
if !f.startedInformers[informerType] {
|
||||
f.wg.Add(1)
|
||||
// We need a new variable in each loop iteration,
|
||||
// otherwise the goroutine would use the loop variable
|
||||
// and that keeps changing.
|
||||
informer := informer
|
||||
go func() {
|
||||
defer f.wg.Done()
|
||||
informer.Run(stopCh)
|
||||
}()
|
||||
go informer.Run(stopCh)
|
||||
f.startedInformers[informerType] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Shutdown() {
|
||||
f.lock.Lock()
|
||||
f.shuttingDown = true
|
||||
f.lock.Unlock()
|
||||
|
||||
// Will return immediately if there is nothing to wait for.
|
||||
f.wg.Wait()
|
||||
}
|
||||
|
||||
// WaitForCacheSync waits for all started informers' cache were synced.
|
||||
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
|
||||
informers := func() map[reflect.Type]cache.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
@@ -208,57 +184,10 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal
|
||||
|
||||
// SharedInformerFactory provides shared informers for resources in all known
|
||||
// API group versions.
|
||||
//
|
||||
// It is typically used like this:
|
||||
//
|
||||
// ctx, cancel := context.Background()
|
||||
// defer cancel()
|
||||
// factory := NewSharedInformerFactory(client, resyncPeriod)
|
||||
// defer factory.WaitForStop() // Returns immediately if nothing was started.
|
||||
// genericInformer := factory.ForResource(resource)
|
||||
// typedInformer := factory.SomeAPIGroup().V1().SomeType()
|
||||
// factory.Start(ctx.Done()) // Start processing these informers.
|
||||
// synced := factory.WaitForCacheSync(ctx.Done())
|
||||
// for v, ok := range synced {
|
||||
// if !ok {
|
||||
// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Creating informers can also be created after Start, but then
|
||||
// // Start must be called again:
|
||||
// anotherGenericInformer := factory.ForResource(resource)
|
||||
// factory.Start(ctx.Done())
|
||||
type SharedInformerFactory interface {
|
||||
internalinterfaces.SharedInformerFactory
|
||||
|
||||
// Start initializes all requested informers. They are handled in goroutines
|
||||
// which run until the stop channel gets closed.
|
||||
Start(stopCh <-chan struct{})
|
||||
|
||||
// Shutdown marks a factory as shutting down. At that point no new
|
||||
// informers can be started anymore and Start will return without
|
||||
// doing anything.
|
||||
//
|
||||
// In addition, Shutdown blocks until all goroutines have terminated. For that
|
||||
// to happen, the close channel(s) that they were started with must be closed,
|
||||
// either before Shutdown gets called or while it is waiting.
|
||||
//
|
||||
// Shutdown may be called multiple times, even concurrently. All such calls will
|
||||
// block until all goroutines have terminated.
|
||||
Shutdown()
|
||||
|
||||
// WaitForCacheSync blocks until all started informers' caches were synced
|
||||
// or the stop channel gets closed.
|
||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
||||
|
||||
// ForResource gives generic access to a shared informer of the matching type.
|
||||
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
||||
|
||||
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
|
||||
// client.
|
||||
InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer
|
||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
||||
|
||||
Admissionregistration() admissionregistration.Interface
|
||||
Internal() apiserverinternal.Interface
|
||||
|
||||
@@ -47,7 +47,6 @@ import (
|
||||
flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1"
|
||||
flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -273,10 +272,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case networkingv1.SchemeGroupVersion.WithResource("networkpolicies"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1().NetworkPolicies().Informer()}, nil
|
||||
|
||||
// Group=networking.k8s.io, Version=v1alpha1
|
||||
case networkingv1alpha1.SchemeGroupVersion.WithResource("clustercidrs"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().ClusterCIDRs().Informer()}, nil
|
||||
|
||||
// Group=networking.k8s.io, Version=v1beta1
|
||||
case networkingv1beta1.SchemeGroupVersion.WithResource("ingresses"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1beta1().Ingresses().Informer()}, nil
|
||||
|
||||
@@ -21,7 +21,6 @@ package networking
|
||||
import (
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
v1 "k8s.io/client-go/informers/networking/v1"
|
||||
v1alpha1 "k8s.io/client-go/informers/networking/v1alpha1"
|
||||
v1beta1 "k8s.io/client-go/informers/networking/v1beta1"
|
||||
)
|
||||
|
||||
@@ -29,8 +28,6 @@ import (
|
||||
type Interface interface {
|
||||
// V1 provides access to shared informers for resources in V1.
|
||||
V1() v1.Interface
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
}
|
||||
@@ -51,11 +48,6 @@ func (g *group) V1() v1.Interface {
|
||||
return v1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V1beta1 returns a new v1beta1.Interface.
|
||||
func (g *group) V1beta1() v1beta1.Interface {
|
||||
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
|
||||
@@ -1,89 +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 informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
kubernetes "k8s.io/client-go/kubernetes"
|
||||
v1alpha1 "k8s.io/client-go/listers/networking/v1alpha1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ClusterCIDRInformer provides access to a shared informer and lister for
|
||||
// ClusterCIDRs.
|
||||
type ClusterCIDRInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.ClusterCIDRLister
|
||||
}
|
||||
|
||||
type clusterCIDRInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewClusterCIDRInformer constructs a new informer for ClusterCIDR type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewClusterCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredClusterCIDRInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredClusterCIDRInformer constructs a new informer for ClusterCIDR type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredClusterCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.NetworkingV1alpha1().ClusterCIDRs().List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.NetworkingV1alpha1().ClusterCIDRs().Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&networkingv1alpha1.ClusterCIDR{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *clusterCIDRInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredClusterCIDRInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *clusterCIDRInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&networkingv1alpha1.ClusterCIDR{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *clusterCIDRInformer) Lister() v1alpha1.ClusterCIDRLister {
|
||||
return v1alpha1.NewClusterCIDRLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -1,45 +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 informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// ClusterCIDRs returns a ClusterCIDRInformer.
|
||||
ClusterCIDRs() ClusterCIDRInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// ClusterCIDRs returns a ClusterCIDRInformer.
|
||||
func (v *version) ClusterCIDRs() ClusterCIDRInformer {
|
||||
return &clusterCIDRInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import (
|
||||
appsv1beta1 "k8s.io/client-go/kubernetes/typed/apps/v1beta1"
|
||||
appsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2"
|
||||
authenticationv1 "k8s.io/client-go/kubernetes/typed/authentication/v1"
|
||||
authenticationv1alpha1 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1"
|
||||
authenticationv1beta1 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1"
|
||||
authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
|
||||
authorizationv1beta1 "k8s.io/client-go/kubernetes/typed/authorization/v1beta1"
|
||||
@@ -54,7 +53,6 @@ import (
|
||||
flowcontrolv1beta1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1"
|
||||
flowcontrolv1beta2 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2"
|
||||
networkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1"
|
||||
networkingv1alpha1 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1"
|
||||
networkingv1beta1 "k8s.io/client-go/kubernetes/typed/networking/v1beta1"
|
||||
nodev1 "k8s.io/client-go/kubernetes/typed/node/v1"
|
||||
nodev1alpha1 "k8s.io/client-go/kubernetes/typed/node/v1alpha1"
|
||||
@@ -83,7 +81,6 @@ type Interface interface {
|
||||
AppsV1beta1() appsv1beta1.AppsV1beta1Interface
|
||||
AppsV1beta2() appsv1beta2.AppsV1beta2Interface
|
||||
AuthenticationV1() authenticationv1.AuthenticationV1Interface
|
||||
AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface
|
||||
AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface
|
||||
AuthorizationV1() authorizationv1.AuthorizationV1Interface
|
||||
AuthorizationV1beta1() authorizationv1beta1.AuthorizationV1beta1Interface
|
||||
@@ -107,7 +104,6 @@ type Interface interface {
|
||||
FlowcontrolV1beta1() flowcontrolv1beta1.FlowcontrolV1beta1Interface
|
||||
FlowcontrolV1beta2() flowcontrolv1beta2.FlowcontrolV1beta2Interface
|
||||
NetworkingV1() networkingv1.NetworkingV1Interface
|
||||
NetworkingV1alpha1() networkingv1alpha1.NetworkingV1alpha1Interface
|
||||
NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface
|
||||
NodeV1() nodev1.NodeV1Interface
|
||||
NodeV1alpha1() nodev1alpha1.NodeV1alpha1Interface
|
||||
@@ -136,7 +132,6 @@ type Clientset struct {
|
||||
appsV1beta1 *appsv1beta1.AppsV1beta1Client
|
||||
appsV1beta2 *appsv1beta2.AppsV1beta2Client
|
||||
authenticationV1 *authenticationv1.AuthenticationV1Client
|
||||
authenticationV1alpha1 *authenticationv1alpha1.AuthenticationV1alpha1Client
|
||||
authenticationV1beta1 *authenticationv1beta1.AuthenticationV1beta1Client
|
||||
authorizationV1 *authorizationv1.AuthorizationV1Client
|
||||
authorizationV1beta1 *authorizationv1beta1.AuthorizationV1beta1Client
|
||||
@@ -160,7 +155,6 @@ type Clientset struct {
|
||||
flowcontrolV1beta1 *flowcontrolv1beta1.FlowcontrolV1beta1Client
|
||||
flowcontrolV1beta2 *flowcontrolv1beta2.FlowcontrolV1beta2Client
|
||||
networkingV1 *networkingv1.NetworkingV1Client
|
||||
networkingV1alpha1 *networkingv1alpha1.NetworkingV1alpha1Client
|
||||
networkingV1beta1 *networkingv1beta1.NetworkingV1beta1Client
|
||||
nodeV1 *nodev1.NodeV1Client
|
||||
nodeV1alpha1 *nodev1alpha1.NodeV1alpha1Client
|
||||
@@ -213,11 +207,6 @@ func (c *Clientset) AuthenticationV1() authenticationv1.AuthenticationV1Interfac
|
||||
return c.authenticationV1
|
||||
}
|
||||
|
||||
// AuthenticationV1alpha1 retrieves the AuthenticationV1alpha1Client
|
||||
func (c *Clientset) AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface {
|
||||
return c.authenticationV1alpha1
|
||||
}
|
||||
|
||||
// AuthenticationV1beta1 retrieves the AuthenticationV1beta1Client
|
||||
func (c *Clientset) AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface {
|
||||
return c.authenticationV1beta1
|
||||
@@ -333,11 +322,6 @@ func (c *Clientset) NetworkingV1() networkingv1.NetworkingV1Interface {
|
||||
return c.networkingV1
|
||||
}
|
||||
|
||||
// NetworkingV1alpha1 retrieves the NetworkingV1alpha1Client
|
||||
func (c *Clientset) NetworkingV1alpha1() networkingv1alpha1.NetworkingV1alpha1Interface {
|
||||
return c.networkingV1alpha1
|
||||
}
|
||||
|
||||
// NetworkingV1beta1 retrieves the NetworkingV1beta1Client
|
||||
func (c *Clientset) NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface {
|
||||
return c.networkingV1beta1
|
||||
@@ -485,10 +469,6 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.authenticationV1alpha1, err = authenticationv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.authenticationV1beta1, err = authenticationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -581,10 +561,6 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.networkingV1alpha1, err = networkingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.networkingV1beta1, err = networkingv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -673,7 +649,6 @@ func New(c rest.Interface) *Clientset {
|
||||
cs.appsV1beta1 = appsv1beta1.New(c)
|
||||
cs.appsV1beta2 = appsv1beta2.New(c)
|
||||
cs.authenticationV1 = authenticationv1.New(c)
|
||||
cs.authenticationV1alpha1 = authenticationv1alpha1.New(c)
|
||||
cs.authenticationV1beta1 = authenticationv1beta1.New(c)
|
||||
cs.authorizationV1 = authorizationv1.New(c)
|
||||
cs.authorizationV1beta1 = authorizationv1beta1.New(c)
|
||||
@@ -697,7 +672,6 @@ func New(c rest.Interface) *Clientset {
|
||||
cs.flowcontrolV1beta1 = flowcontrolv1beta1.New(c)
|
||||
cs.flowcontrolV1beta2 = flowcontrolv1beta2.New(c)
|
||||
cs.networkingV1 = networkingv1.New(c)
|
||||
cs.networkingV1alpha1 = networkingv1alpha1.New(c)
|
||||
cs.networkingV1beta1 = networkingv1beta1.New(c)
|
||||
cs.nodeV1 = nodev1.New(c)
|
||||
cs.nodeV1alpha1 = nodev1alpha1.New(c)
|
||||
|
||||
@@ -38,8 +38,6 @@ import (
|
||||
fakeappsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake"
|
||||
authenticationv1 "k8s.io/client-go/kubernetes/typed/authentication/v1"
|
||||
fakeauthenticationv1 "k8s.io/client-go/kubernetes/typed/authentication/v1/fake"
|
||||
authenticationv1alpha1 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1"
|
||||
fakeauthenticationv1alpha1 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/fake"
|
||||
authenticationv1beta1 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1"
|
||||
fakeauthenticationv1beta1 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake"
|
||||
authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
|
||||
@@ -86,8 +84,6 @@ import (
|
||||
fakeflowcontrolv1beta2 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake"
|
||||
networkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1"
|
||||
fakenetworkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1/fake"
|
||||
networkingv1alpha1 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1"
|
||||
fakenetworkingv1alpha1 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake"
|
||||
networkingv1beta1 "k8s.io/client-go/kubernetes/typed/networking/v1beta1"
|
||||
fakenetworkingv1beta1 "k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake"
|
||||
nodev1 "k8s.io/client-go/kubernetes/typed/node/v1"
|
||||
@@ -206,11 +202,6 @@ func (c *Clientset) AuthenticationV1() authenticationv1.AuthenticationV1Interfac
|
||||
return &fakeauthenticationv1.FakeAuthenticationV1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// AuthenticationV1alpha1 retrieves the AuthenticationV1alpha1Client
|
||||
func (c *Clientset) AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface {
|
||||
return &fakeauthenticationv1alpha1.FakeAuthenticationV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// AuthenticationV1beta1 retrieves the AuthenticationV1beta1Client
|
||||
func (c *Clientset) AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface {
|
||||
return &fakeauthenticationv1beta1.FakeAuthenticationV1beta1{Fake: &c.Fake}
|
||||
@@ -326,11 +317,6 @@ func (c *Clientset) NetworkingV1() networkingv1.NetworkingV1Interface {
|
||||
return &fakenetworkingv1.FakeNetworkingV1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// NetworkingV1alpha1 retrieves the NetworkingV1alpha1Client
|
||||
func (c *Clientset) NetworkingV1alpha1() networkingv1alpha1.NetworkingV1alpha1Interface {
|
||||
return &fakenetworkingv1alpha1.FakeNetworkingV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// NetworkingV1beta1 retrieves the NetworkingV1beta1Client
|
||||
func (c *Clientset) NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface {
|
||||
return &fakenetworkingv1beta1.FakeNetworkingV1beta1{Fake: &c.Fake}
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1"
|
||||
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
|
||||
authorizationv1 "k8s.io/api/authorization/v1"
|
||||
authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
|
||||
@@ -50,7 +49,6 @@ import (
|
||||
flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1"
|
||||
flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -84,7 +82,6 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
appsv1beta1.AddToScheme,
|
||||
appsv1beta2.AddToScheme,
|
||||
authenticationv1.AddToScheme,
|
||||
authenticationv1alpha1.AddToScheme,
|
||||
authenticationv1beta1.AddToScheme,
|
||||
authorizationv1.AddToScheme,
|
||||
authorizationv1beta1.AddToScheme,
|
||||
@@ -108,7 +105,6 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
flowcontrolv1beta1.AddToScheme,
|
||||
flowcontrolv1beta2.AddToScheme,
|
||||
networkingv1.AddToScheme,
|
||||
networkingv1alpha1.AddToScheme,
|
||||
networkingv1beta1.AddToScheme,
|
||||
nodev1.AddToScheme,
|
||||
nodev1alpha1.AddToScheme,
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1"
|
||||
authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
|
||||
authorizationv1 "k8s.io/api/authorization/v1"
|
||||
authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
|
||||
@@ -50,7 +49,6 @@ import (
|
||||
flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1"
|
||||
flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -84,7 +82,6 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
appsv1beta1.AddToScheme,
|
||||
appsv1beta2.AddToScheme,
|
||||
authenticationv1.AddToScheme,
|
||||
authenticationv1alpha1.AddToScheme,
|
||||
authenticationv1beta1.AddToScheme,
|
||||
authorizationv1.AddToScheme,
|
||||
authorizationv1beta1.AddToScheme,
|
||||
@@ -108,7 +105,6 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
flowcontrolv1beta1.AddToScheme,
|
||||
flowcontrolv1beta2.AddToScheme,
|
||||
networkingv1.AddToScheme,
|
||||
networkingv1alpha1.AddToScheme,
|
||||
networkingv1beta1.AddToScheme,
|
||||
nodev1.AddToScheme,
|
||||
nodev1alpha1.AddToScheme,
|
||||
|
||||
@@ -1,107 +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 v1alpha1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
v1alpha1 "k8s.io/api/authentication/v1alpha1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type AuthenticationV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
SelfSubjectReviewsGetter
|
||||
}
|
||||
|
||||
// AuthenticationV1alpha1Client is used to interact with features provided by the authentication.k8s.io group.
|
||||
type AuthenticationV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *AuthenticationV1alpha1Client) SelfSubjectReviews() SelfSubjectReviewInterface {
|
||||
return newSelfSubjectReviews(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AuthenticationV1alpha1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*AuthenticationV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
httpClient, err := rest.HTTPClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewForConfigAndClient(&config, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new AuthenticationV1alpha1Client for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AuthenticationV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AuthenticationV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AuthenticationV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AuthenticationV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AuthenticationV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *AuthenticationV1alpha1Client {
|
||||
return &AuthenticationV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *AuthenticationV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -1,20 +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.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,20 +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 has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,40 +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 (
|
||||
v1alpha1 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeAuthenticationV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeAuthenticationV1alpha1) SelfSubjectReviews() v1alpha1.SelfSubjectReviewInterface {
|
||||
return &FakeSelfSubjectReviews{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeAuthenticationV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -1,47 +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"
|
||||
|
||||
v1alpha1 "k8s.io/api/authentication/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeSelfSubjectReviews implements SelfSubjectReviewInterface
|
||||
type FakeSelfSubjectReviews struct {
|
||||
Fake *FakeAuthenticationV1alpha1
|
||||
}
|
||||
|
||||
var selfsubjectreviewsResource = schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1alpha1", Resource: "selfsubjectreviews"}
|
||||
|
||||
var selfsubjectreviewsKind = schema.GroupVersionKind{Group: "authentication.k8s.io", Version: "v1alpha1", Kind: "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 *v1alpha1.SelfSubjectReview, opts v1.CreateOptions) (result *v1alpha1.SelfSubjectReview, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(selfsubjectreviewsResource, selfSubjectReview), &v1alpha1.SelfSubjectReview{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.SelfSubjectReview), err
|
||||
}
|
||||
@@ -1,21 +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 v1alpha1
|
||||
|
||||
type SelfSubjectReviewExpansion interface{}
|
||||
@@ -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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "k8s.io/api/authentication/v1alpha1"
|
||||
v1 "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 *v1alpha1.SelfSubjectReview, opts v1.CreateOptions) (*v1alpha1.SelfSubjectReview, error)
|
||||
SelfSubjectReviewExpansion
|
||||
}
|
||||
|
||||
// selfSubjectReviews implements SelfSubjectReviewInterface
|
||||
type selfSubjectReviews struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newSelfSubjectReviews returns a SelfSubjectReviews
|
||||
func newSelfSubjectReviews(c *AuthenticationV1alpha1Client) *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 *v1alpha1.SelfSubjectReview, opts v1.CreateOptions) (result *v1alpha1.SelfSubjectReview, err error) {
|
||||
result = &v1alpha1.SelfSubjectReview{}
|
||||
err = c.client.Post().
|
||||
Resource("selfsubjectreviews").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(selfSubjectReview).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package fake
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -68,7 +68,7 @@ func (c *FakePods) GetLogs(name string, opts *v1.PodLogOptions) *restclient.Requ
|
||||
Client: fakerest.CreateHTTPClient(func(request *http.Request) (*http.Response, error) {
|
||||
resp := &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(strings.NewReader("fake logs")),
|
||||
Body: ioutil.NopCloser(strings.NewReader("fake logs")),
|
||||
}
|
||||
return resp, nil
|
||||
}),
|
||||
|
||||
@@ -1,197 +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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
json "encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1"
|
||||
scheme "k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// ClusterCIDRsGetter has a method to return a ClusterCIDRInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ClusterCIDRsGetter interface {
|
||||
ClusterCIDRs() ClusterCIDRInterface
|
||||
}
|
||||
|
||||
// ClusterCIDRInterface has methods to work with ClusterCIDR resources.
|
||||
type ClusterCIDRInterface interface {
|
||||
Create(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.CreateOptions) (*v1alpha1.ClusterCIDR, error)
|
||||
Update(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.UpdateOptions) (*v1alpha1.ClusterCIDR, 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) (*v1alpha1.ClusterCIDR, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterCIDRList, error)
|
||||
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 *v1alpha1.ClusterCIDR, err error)
|
||||
Apply(ctx context.Context, clusterCIDR *networkingv1alpha1.ClusterCIDRApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterCIDR, err error)
|
||||
ClusterCIDRExpansion
|
||||
}
|
||||
|
||||
// clusterCIDRs implements ClusterCIDRInterface
|
||||
type clusterCIDRs struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newClusterCIDRs returns a ClusterCIDRs
|
||||
func newClusterCIDRs(c *NetworkingV1alpha1Client) *clusterCIDRs {
|
||||
return &clusterCIDRs{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the clusterCIDR, and returns the corresponding clusterCIDR object, and an error if there is any.
|
||||
func (c *clusterCIDRs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
result = &v1alpha1.ClusterCIDR{}
|
||||
err = c.client.Get().
|
||||
Resource("clustercidrs").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ClusterCIDRs that match those selectors.
|
||||
func (c *clusterCIDRs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterCIDRList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.ClusterCIDRList{}
|
||||
err = c.client.Get().
|
||||
Resource("clustercidrs").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested clusterCIDRs.
|
||||
func (c *clusterCIDRs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("clustercidrs").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a clusterCIDR and creates it. Returns the server's representation of the clusterCIDR, and an error, if there is any.
|
||||
func (c *clusterCIDRs) Create(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.CreateOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
result = &v1alpha1.ClusterCIDR{}
|
||||
err = c.client.Post().
|
||||
Resource("clustercidrs").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(clusterCIDR).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a clusterCIDR and updates it. Returns the server's representation of the clusterCIDR, and an error, if there is any.
|
||||
func (c *clusterCIDRs) Update(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.UpdateOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
result = &v1alpha1.ClusterCIDR{}
|
||||
err = c.client.Put().
|
||||
Resource("clustercidrs").
|
||||
Name(clusterCIDR.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(clusterCIDR).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the clusterCIDR and deletes it. Returns an error if one occurs.
|
||||
func (c *clusterCIDRs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("clustercidrs").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *clusterCIDRs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("clustercidrs").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched clusterCIDR.
|
||||
func (c *clusterCIDRs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
result = &v1alpha1.ClusterCIDR{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("clustercidrs").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Apply takes the given apply declarative configuration, applies it and returns the applied clusterCIDR.
|
||||
func (c *clusterCIDRs) Apply(ctx context.Context, clusterCIDR *networkingv1alpha1.ClusterCIDRApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
if clusterCIDR == nil {
|
||||
return nil, fmt.Errorf("clusterCIDR provided to Apply must not be nil")
|
||||
}
|
||||
patchOpts := opts.ToPatchOptions()
|
||||
data, err := json.Marshal(clusterCIDR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := clusterCIDR.Name
|
||||
if name == nil {
|
||||
return nil, fmt.Errorf("clusterCIDR.Name must be provided to Apply")
|
||||
}
|
||||
result = &v1alpha1.ClusterCIDR{}
|
||||
err = c.client.Patch(types.ApplyPatchType).
|
||||
Resource("clustercidrs").
|
||||
Name(*name).
|
||||
VersionedParams(&patchOpts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -1,20 +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.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,20 +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 has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,146 +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"
|
||||
json "encoding/json"
|
||||
"fmt"
|
||||
|
||||
v1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeClusterCIDRs implements ClusterCIDRInterface
|
||||
type FakeClusterCIDRs struct {
|
||||
Fake *FakeNetworkingV1alpha1
|
||||
}
|
||||
|
||||
var clustercidrsResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1alpha1", Resource: "clustercidrs"}
|
||||
|
||||
var clustercidrsKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1alpha1", Kind: "ClusterCIDR"}
|
||||
|
||||
// Get takes name of the clusterCIDR, and returns the corresponding clusterCIDR object, and an error if there is any.
|
||||
func (c *FakeClusterCIDRs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(clustercidrsResource, name), &v1alpha1.ClusterCIDR{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ClusterCIDR), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ClusterCIDRs that match those selectors.
|
||||
func (c *FakeClusterCIDRs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterCIDRList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(clustercidrsResource, clustercidrsKind, opts), &v1alpha1.ClusterCIDRList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.ClusterCIDRList{ListMeta: obj.(*v1alpha1.ClusterCIDRList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.ClusterCIDRList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested clusterCIDRs.
|
||||
func (c *FakeClusterCIDRs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(clustercidrsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a clusterCIDR and creates it. Returns the server's representation of the clusterCIDR, and an error, if there is any.
|
||||
func (c *FakeClusterCIDRs) Create(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.CreateOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(clustercidrsResource, clusterCIDR), &v1alpha1.ClusterCIDR{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ClusterCIDR), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a clusterCIDR and updates it. Returns the server's representation of the clusterCIDR, and an error, if there is any.
|
||||
func (c *FakeClusterCIDRs) Update(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.UpdateOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(clustercidrsResource, clusterCIDR), &v1alpha1.ClusterCIDR{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ClusterCIDR), err
|
||||
}
|
||||
|
||||
// Delete takes name of the clusterCIDR and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeClusterCIDRs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteActionWithOptions(clustercidrsResource, name, opts), &v1alpha1.ClusterCIDR{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeClusterCIDRs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(clustercidrsResource, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.ClusterCIDRList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched clusterCIDR.
|
||||
func (c *FakeClusterCIDRs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(clustercidrsResource, name, pt, data, subresources...), &v1alpha1.ClusterCIDR{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ClusterCIDR), err
|
||||
}
|
||||
|
||||
// Apply takes the given apply declarative configuration, applies it and returns the applied clusterCIDR.
|
||||
func (c *FakeClusterCIDRs) Apply(ctx context.Context, clusterCIDR *networkingv1alpha1.ClusterCIDRApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterCIDR, err error) {
|
||||
if clusterCIDR == nil {
|
||||
return nil, fmt.Errorf("clusterCIDR provided to Apply must not be nil")
|
||||
}
|
||||
data, err := json.Marshal(clusterCIDR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := clusterCIDR.Name
|
||||
if name == nil {
|
||||
return nil, fmt.Errorf("clusterCIDR.Name must be provided to Apply")
|
||||
}
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(clustercidrsResource, *name, types.ApplyPatchType, data), &v1alpha1.ClusterCIDR{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ClusterCIDR), err
|
||||
}
|
||||
@@ -1,40 +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 (
|
||||
v1alpha1 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeNetworkingV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeNetworkingV1alpha1) ClusterCIDRs() v1alpha1.ClusterCIDRInterface {
|
||||
return &FakeClusterCIDRs{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeNetworkingV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -1,21 +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 v1alpha1
|
||||
|
||||
type ClusterCIDRExpansion interface{}
|
||||
@@ -1,107 +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 v1alpha1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
v1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type NetworkingV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
ClusterCIDRsGetter
|
||||
}
|
||||
|
||||
// NetworkingV1alpha1Client is used to interact with features provided by the networking.k8s.io group.
|
||||
type NetworkingV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *NetworkingV1alpha1Client) ClusterCIDRs() ClusterCIDRInterface {
|
||||
return newClusterCIDRs(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new NetworkingV1alpha1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*NetworkingV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
httpClient, err := rest.HTTPClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewForConfigAndClient(&config, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new NetworkingV1alpha1Client for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*NetworkingV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &NetworkingV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new NetworkingV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *NetworkingV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new NetworkingV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *NetworkingV1alpha1Client {
|
||||
return &NetworkingV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *NetworkingV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package kubernetes_test
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestListTimeout(t *testing.T) {
|
||||
if req.URL.Query().Get("timeout") != "21s" {
|
||||
t.Fatal(spew.Sdump(req.URL.Query()))
|
||||
}
|
||||
return &http.Response{StatusCode: http.StatusNotFound, Body: io.NopCloser(&bytes.Buffer{})}, nil
|
||||
return &http.Response{StatusCode: http.StatusNotFound, Body: ioutil.NopCloser(&bytes.Buffer{})}, nil
|
||||
}),
|
||||
}
|
||||
clientConfig := &rest.Config{
|
||||
|
||||
@@ -1,68 +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 lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/api/networking/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ClusterCIDRLister helps list ClusterCIDRs.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ClusterCIDRLister interface {
|
||||
// List lists all ClusterCIDRs in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.ClusterCIDR, err error)
|
||||
// Get retrieves the ClusterCIDR from the index for a given name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.ClusterCIDR, error)
|
||||
ClusterCIDRListerExpansion
|
||||
}
|
||||
|
||||
// clusterCIDRLister implements the ClusterCIDRLister interface.
|
||||
type clusterCIDRLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewClusterCIDRLister returns a new ClusterCIDRLister.
|
||||
func NewClusterCIDRLister(indexer cache.Indexer) ClusterCIDRLister {
|
||||
return &clusterCIDRLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all ClusterCIDRs in the indexer.
|
||||
func (s *clusterCIDRLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterCIDR, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.ClusterCIDR))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the ClusterCIDR from the index for a given name.
|
||||
func (s *clusterCIDRLister) Get(name string) (*v1alpha1.ClusterCIDR, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("clustercidr"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.ClusterCIDR), nil
|
||||
}
|
||||
@@ -1,23 +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 lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ClusterCIDRListerExpansion allows custom methods to be added to
|
||||
// ClusterCIDRLister.
|
||||
type ClusterCIDRListerExpansion interface{}
|
||||
@@ -19,7 +19,7 @@ package metadata
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
@@ -245,7 +245,7 @@ func TestClient(t *testing.T) {
|
||||
t.Fatal(req.URL.String())
|
||||
}
|
||||
defer req.Body.Close()
|
||||
buf, err := io.ReadAll(req.Body)
|
||||
buf, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -272,7 +272,7 @@ func TestClient(t *testing.T) {
|
||||
t.Fatal(req.URL.String())
|
||||
}
|
||||
defer req.Body.Close()
|
||||
buf, err := io.ReadAll(req.Body)
|
||||
buf, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -98,11 +98,6 @@ type Cluster struct {
|
||||
// cluster.
|
||||
// +optional
|
||||
ProxyURL string
|
||||
// DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful
|
||||
// to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on
|
||||
// compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296.
|
||||
// +optional
|
||||
DisableCompression bool
|
||||
// Config holds additional config data that is specific to the exec
|
||||
// plugin with regards to the cluster being authenticated to.
|
||||
//
|
||||
|
||||
@@ -96,11 +96,6 @@ type Cluster struct {
|
||||
// cluster.
|
||||
// +optional
|
||||
ProxyURL string `json:"proxy-url,omitempty"`
|
||||
// DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful
|
||||
// to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on
|
||||
// compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296.
|
||||
// +optional
|
||||
DisableCompression bool `json:"disable-compression,omitempty"`
|
||||
// Config holds additional config data that is specific to the exec
|
||||
// plugin with regards to the cluster being authenticated to.
|
||||
//
|
||||
|
||||
@@ -86,7 +86,6 @@ func autoConvert_v1_Cluster_To_clientauthentication_Cluster(in *Cluster, out *cl
|
||||
out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify
|
||||
out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData))
|
||||
out.ProxyURL = in.ProxyURL
|
||||
out.DisableCompression = in.DisableCompression
|
||||
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Config, &out.Config, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -104,7 +103,6 @@ func autoConvert_clientauthentication_Cluster_To_v1_Cluster(in *clientauthentica
|
||||
out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify
|
||||
out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData))
|
||||
out.ProxyURL = in.ProxyURL
|
||||
out.DisableCompression = in.DisableCompression
|
||||
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Config, &out.Config, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -96,11 +96,6 @@ type Cluster struct {
|
||||
// cluster.
|
||||
// +optional
|
||||
ProxyURL string `json:"proxy-url,omitempty"`
|
||||
// DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful
|
||||
// to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on
|
||||
// compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296.
|
||||
// +optional
|
||||
DisableCompression bool `json:"disable-compression,omitempty"`
|
||||
// Config holds additional config data that is specific to the exec
|
||||
// plugin with regards to the cluster being authenticated to.
|
||||
//
|
||||
|
||||
@@ -86,7 +86,6 @@ func autoConvert_v1beta1_Cluster_To_clientauthentication_Cluster(in *Cluster, ou
|
||||
out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify
|
||||
out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData))
|
||||
out.ProxyURL = in.ProxyURL
|
||||
out.DisableCompression = in.DisableCompression
|
||||
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Config, &out.Config, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -104,7 +103,6 @@ func autoConvert_clientauthentication_Cluster_To_v1beta1_Cluster(in *clientauthe
|
||||
out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify
|
||||
out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData))
|
||||
out.ProxyURL = in.ProxyURL
|
||||
out.DisableCompression = in.DisableCompression
|
||||
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Config, &out.Config, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -199,18 +199,14 @@ func newAuthenticator(c *cache, isTerminalFunc func(int) bool, config *api.ExecC
|
||||
now: time.Now,
|
||||
environ: os.Environ,
|
||||
|
||||
connTracker: connTracker,
|
||||
defaultDialer: defaultDialer,
|
||||
connTracker: connTracker,
|
||||
}
|
||||
|
||||
for _, env := range config.Env {
|
||||
a.env = append(a.env, env.Name+"="+env.Value)
|
||||
}
|
||||
|
||||
// these functions are made comparable and stored in the cache so that repeated clientset
|
||||
// construction with the same rest.Config results in a single TLS cache and Authenticator
|
||||
a.getCert = &transport.GetCertHolder{GetCert: a.cert}
|
||||
a.dial = &transport.DialHolder{Dial: defaultDialer.DialContext}
|
||||
|
||||
return c.put(key, a), nil
|
||||
}
|
||||
|
||||
@@ -265,6 +261,8 @@ type Authenticator struct {
|
||||
now func() time.Time
|
||||
environ func() []string
|
||||
|
||||
// defaultDialer is used for clients which don't specify a custom dialer
|
||||
defaultDialer *connrotation.Dialer
|
||||
// connTracker tracks all connections opened that we need to close when rotating a client certificate
|
||||
connTracker *connrotation.ConnectionTracker
|
||||
|
||||
@@ -275,12 +273,6 @@ type Authenticator struct {
|
||||
mu sync.Mutex
|
||||
cachedCreds *credentials
|
||||
exp time.Time
|
||||
|
||||
// getCert makes Authenticator.cert comparable to support TLS config caching
|
||||
getCert *transport.GetCertHolder
|
||||
// dial is used for clients which do not specify a custom dialer
|
||||
// it is comparable to support TLS config caching
|
||||
dial *transport.DialHolder
|
||||
}
|
||||
|
||||
type credentials struct {
|
||||
@@ -308,21 +300,18 @@ func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error {
|
||||
if c.HasCertCallback() {
|
||||
return errors.New("can't add TLS certificate callback: transport.Config.TLS.GetCert already set")
|
||||
}
|
||||
c.TLS.GetCertHolder = a.getCert // comparable for TLS config caching
|
||||
|
||||
if c.DialHolder != nil {
|
||||
if c.DialHolder.Dial == nil {
|
||||
return errors.New("invalid transport.Config.DialHolder: wrapped Dial function is nil")
|
||||
}
|
||||
c.TLS.GetCert = a.cert
|
||||
|
||||
var d *connrotation.Dialer
|
||||
if c.Dial != nil {
|
||||
// if c has a custom dialer, we have to wrap it
|
||||
// TLS config caching is not supported for this config
|
||||
d := connrotation.NewDialerWithTracker(c.DialHolder.Dial, a.connTracker)
|
||||
c.DialHolder = &transport.DialHolder{Dial: d.DialContext}
|
||||
d = connrotation.NewDialerWithTracker(c.Dial, a.connTracker)
|
||||
} else {
|
||||
c.DialHolder = a.dial // comparable for TLS config caching
|
||||
d = a.defaultDialer
|
||||
}
|
||||
|
||||
c.Dial = d.DialContext
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package exec_test // separate package to prevent circular import
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
// TestExecTLSCache asserts the semantics of the TLS cache when exec auth is used.
|
||||
//
|
||||
// In particular, when:
|
||||
// - multiple identical rest configs exist as distinct objects, and
|
||||
// - these rest configs use exec auth, and
|
||||
// - these rest configs are used to create distinct clientsets, then
|
||||
//
|
||||
// the underlying TLS config is shared between those clientsets.
|
||||
func TestExecTLSCache(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
config1 := &rest.Config{
|
||||
Host: "https://localhost",
|
||||
ExecProvider: &clientcmdapi.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1",
|
||||
InteractiveMode: clientcmdapi.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
}
|
||||
client1 := clientset.NewForConfigOrDie(config1)
|
||||
|
||||
config2 := &rest.Config{
|
||||
Host: "https://localhost",
|
||||
ExecProvider: &clientcmdapi.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1",
|
||||
InteractiveMode: clientcmdapi.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
}
|
||||
client2 := clientset.NewForConfigOrDie(config2)
|
||||
|
||||
config3 := &rest.Config{
|
||||
Host: "https://localhost",
|
||||
ExecProvider: &clientcmdapi.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
Args: []string{"make this exec auth different"},
|
||||
APIVersion: "client.authentication.k8s.io/v1",
|
||||
InteractiveMode: clientcmdapi.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
}
|
||||
client3 := clientset.NewForConfigOrDie(config3)
|
||||
|
||||
_, _ = client1.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
|
||||
_, _ = client2.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
|
||||
_, _ = client3.CoreV1().PersistentVolumes().List(ctx, metav1.ListOptions{})
|
||||
|
||||
rt1 := client1.RESTClient().(*rest.RESTClient).Client.Transport
|
||||
rt2 := client2.RESTClient().(*rest.RESTClient).Client.Transport
|
||||
rt3 := client3.RESTClient().(*rest.RESTClient).Client.Transport
|
||||
|
||||
tlsConfig1, err := utilnet.TLSClientConfig(rt1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tlsConfig2, err := utilnet.TLSClientConfig(rt2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tlsConfig3, err := utilnet.TLSClientConfig(rt3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if tlsConfig1 == nil || tlsConfig2 == nil || tlsConfig3 == nil {
|
||||
t.Fatal("expected non-nil TLS configs")
|
||||
}
|
||||
|
||||
if tlsConfig1 != tlsConfig2 {
|
||||
t.Fatal("expected the same TLS config for matching exec config via rest config")
|
||||
}
|
||||
|
||||
if tlsConfig1 == tlsConfig3 {
|
||||
t.Fatal("expected different TLS config for non-matching exec config via rest config")
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -888,7 +888,7 @@ func TestRoundTripper(t *testing.T) {
|
||||
}
|
||||
a.environ = environ
|
||||
a.now = now
|
||||
a.stderr = io.Discard
|
||||
a.stderr = ioutil.Discard
|
||||
|
||||
tc := &transport.Config{}
|
||||
if err := a.UpdateTransportConfig(tc); err != nil {
|
||||
@@ -1005,7 +1005,7 @@ func TestAuthorizationHeaderPresentCancelsExecAction(t *testing.T) {
|
||||
cert := func() (*tls.Certificate, error) {
|
||||
return nil, nil
|
||||
}
|
||||
tc := &transport.Config{TLS: transport.TLSConfig{Insecure: true, GetCertHolder: &transport.GetCertHolder{GetCert: cert}}}
|
||||
tc := &transport.Config{TLS: transport.TLSConfig{Insecure: true, GetCert: cert}}
|
||||
test.setTransportConfig(tc)
|
||||
|
||||
if err := a.UpdateTransportConfig(tc); err != nil {
|
||||
@@ -1051,7 +1051,7 @@ func TestTLSCredentials(t *testing.T) {
|
||||
return []string{"TEST_OUTPUT=" + string(data)}
|
||||
}
|
||||
a.now = func() time.Time { return now }
|
||||
a.stderr = io.Discard
|
||||
a.stderr = ioutil.Discard
|
||||
|
||||
// We're not interested in server's cert, this test is about client cert.
|
||||
tc := &transport.Config{TLS: transport.TLSConfig{Insecure: true}}
|
||||
@@ -1134,7 +1134,7 @@ func TestConcurrentUpdateTransportConfig(t *testing.T) {
|
||||
}
|
||||
a.environ = environ
|
||||
a.now = now
|
||||
a.stderr = io.Discard
|
||||
a.stderr = ioutil.Discard
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -301,7 +301,7 @@ func tokenEndpoint(client *http.Client, issuer string) (string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
36
plugin/pkg/client/auth/openstack/openstack_stub.go
Normal file
36
plugin/pkg/client/auth/openstack/openstack_stub.go
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2020 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 openstack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := rest.RegisterAuthProviderPlugin("openstack", newOpenstackAuthProvider); err != nil {
|
||||
klog.Fatalf("Failed to register openstack auth plugin: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func newOpenstackAuthProvider(_ string, _ map[string]string, _ rest.AuthProviderConfigPersister) (rest.AuthProvider, error) {
|
||||
return nil, errors.New(`The openstack auth plugin has been removed.
|
||||
Please use the "client-keystone-auth" kubectl/client-go credential plugin instead.
|
||||
See https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-client-keystone-auth.md for further details`)
|
||||
}
|
||||
@@ -23,4 +23,5 @@ import (
|
||||
// Initialize client auth plugins for cloud providers.
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -518,7 +519,7 @@ func InClusterConfig() (*Config, error) {
|
||||
return nil, ErrNotInCluster
|
||||
}
|
||||
|
||||
token, err := os.ReadFile(tokenFile)
|
||||
token, err := ioutil.ReadFile(tokenFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -571,7 +572,10 @@ func LoadTLSFiles(c *Config) error {
|
||||
}
|
||||
|
||||
c.KeyData, err = dataFromSliceOrFile(c.KeyData, c.KeyFile)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dataFromSliceOrFile returns data from the slice (if non-empty), or from the file,
|
||||
@@ -581,7 +585,7 @@ func dataFromSliceOrFile(data []byte, file string) ([]byte, error) {
|
||||
return data, nil
|
||||
}
|
||||
if len(file) > 0 {
|
||||
fileData, err := os.ReadFile(file)
|
||||
fileData, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
@@ -163,22 +163,18 @@ func TestRESTClientLimiter(t *testing.T) {
|
||||
Limiter flowcontrol.RateLimiter
|
||||
}{
|
||||
{
|
||||
Name: "with no QPS",
|
||||
Config: Config{},
|
||||
Limiter: flowcontrol.NewTokenBucketRateLimiter(5, 10),
|
||||
},
|
||||
{
|
||||
Name: "with QPS:10",
|
||||
Config: Config{QPS: 10},
|
||||
Limiter: flowcontrol.NewTokenBucketRateLimiter(10, 10),
|
||||
},
|
||||
{
|
||||
Name: "with QPS:-1",
|
||||
Config: Config{QPS: -1},
|
||||
Limiter: nil,
|
||||
},
|
||||
{
|
||||
Name: "with RateLimiter",
|
||||
Config: Config{
|
||||
RateLimiter: flowcontrol.NewTokenBucketRateLimiter(11, 12),
|
||||
},
|
||||
@@ -195,7 +191,7 @@ func TestRESTClientLimiter(t *testing.T) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(testCase.Limiter, client.rateLimiter) {
|
||||
t.Fatalf("unexpected rate limiter: %#v, expected %#v at %s", client.rateLimiter, testCase.Limiter, testCase.Name)
|
||||
t.Fatalf("unexpected rate limiter: %#v", client.rateLimiter)
|
||||
}
|
||||
})
|
||||
t.Run("Unversioned_"+testCase.Name, func(t *testing.T) {
|
||||
@@ -207,7 +203,7 @@ func TestRESTClientLimiter(t *testing.T) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(testCase.Limiter, client.rateLimiter) {
|
||||
t.Fatalf("unexpected rate limiter: %#v, expected %#v at %s", client.rateLimiter, testCase.Limiter, testCase.Name)
|
||||
t.Fatalf("unexpected rate limiter: %#v", client.rateLimiter)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -55,7 +55,6 @@ func ConfigToExecCluster(config *Config) (*clientauthenticationapi.Cluster, erro
|
||||
InsecureSkipTLSVerify: config.Insecure,
|
||||
CertificateAuthorityData: caData,
|
||||
ProxyURL: proxyURL,
|
||||
DisableCompression: config.DisableCompression,
|
||||
Config: config.ExecProvider.Config,
|
||||
}, nil
|
||||
}
|
||||
@@ -80,7 +79,6 @@ func ExecClusterToConfig(cluster *clientauthenticationapi.Cluster) (*Config, err
|
||||
ServerName: cluster.TLSServerName,
|
||||
CAData: cluster.CertificateAuthorityData,
|
||||
},
|
||||
Proxy: proxy,
|
||||
DisableCompression: cluster.DisableCompression,
|
||||
Proxy: proxy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"strconv"
|
||||
@@ -437,7 +437,7 @@ func (r *Request) Body(obj interface{}) *Request {
|
||||
}
|
||||
switch t := obj.(type) {
|
||||
case string:
|
||||
data, err := os.ReadFile(t)
|
||||
data, err := ioutil.ReadFile(t)
|
||||
if err != nil {
|
||||
r.err = err
|
||||
return r
|
||||
@@ -508,87 +508,6 @@ func (r *Request) URL() *url.URL {
|
||||
return finalURL
|
||||
}
|
||||
|
||||
// finalURLTemplate is similar to URL(), but will make all specific parameter values equal
|
||||
// - instead of name or namespace, "{name}" and "{namespace}" will be used, and all query
|
||||
// parameters will be reset. This creates a copy of the url so as not to change the
|
||||
// underlying object.
|
||||
func (r Request) finalURLTemplate() url.URL {
|
||||
newParams := url.Values{}
|
||||
v := []string{"{value}"}
|
||||
for k := range r.params {
|
||||
newParams[k] = v
|
||||
}
|
||||
r.params = newParams
|
||||
u := r.URL()
|
||||
if u == nil {
|
||||
return url.URL{}
|
||||
}
|
||||
|
||||
segments := strings.Split(u.Path, "/")
|
||||
groupIndex := 0
|
||||
index := 0
|
||||
trimmedBasePath := ""
|
||||
if r.c.base != nil && strings.Contains(u.Path, r.c.base.Path) {
|
||||
p := strings.TrimPrefix(u.Path, r.c.base.Path)
|
||||
if !strings.HasPrefix(p, "/") {
|
||||
p = "/" + p
|
||||
}
|
||||
// store the base path that we have trimmed so we can append it
|
||||
// before returning the URL
|
||||
trimmedBasePath = r.c.base.Path
|
||||
segments = strings.Split(p, "/")
|
||||
groupIndex = 1
|
||||
}
|
||||
if len(segments) <= 2 {
|
||||
return *u
|
||||
}
|
||||
|
||||
const CoreGroupPrefix = "api"
|
||||
const NamedGroupPrefix = "apis"
|
||||
isCoreGroup := segments[groupIndex] == CoreGroupPrefix
|
||||
isNamedGroup := segments[groupIndex] == NamedGroupPrefix
|
||||
if isCoreGroup {
|
||||
// checking the case of core group with /api/v1/... format
|
||||
index = groupIndex + 2
|
||||
} else if isNamedGroup {
|
||||
// checking the case of named group with /apis/apps/v1/... format
|
||||
index = groupIndex + 3
|
||||
} else {
|
||||
// this should not happen that the only two possibilities are /api... and /apis..., just want to put an
|
||||
// outlet here in case more API groups are added in future if ever possible:
|
||||
// https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups
|
||||
// if a wrong API groups name is encountered, return the {prefix} for url.Path
|
||||
u.Path = "/{prefix}"
|
||||
u.RawQuery = ""
|
||||
return *u
|
||||
}
|
||||
// switch segLength := len(segments) - index; segLength {
|
||||
switch {
|
||||
// case len(segments) - index == 1:
|
||||
// resource (with no name) do nothing
|
||||
case len(segments)-index == 2:
|
||||
// /$RESOURCE/$NAME: replace $NAME with {name}
|
||||
segments[index+1] = "{name}"
|
||||
case len(segments)-index == 3:
|
||||
if segments[index+2] == "finalize" || segments[index+2] == "status" {
|
||||
// /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name}
|
||||
segments[index+1] = "{name}"
|
||||
} else {
|
||||
// /namespace/$NAMESPACE/$RESOURCE: replace $NAMESPACE with {namespace}
|
||||
segments[index+1] = "{namespace}"
|
||||
}
|
||||
case len(segments)-index >= 4:
|
||||
segments[index+1] = "{namespace}"
|
||||
// /namespace/$NAMESPACE/$RESOURCE/$NAME: replace $NAMESPACE with {namespace}, $NAME with {name}
|
||||
if segments[index+3] != "finalize" && segments[index+3] != "status" {
|
||||
// /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name}
|
||||
segments[index+3] = "{name}"
|
||||
}
|
||||
}
|
||||
u.Path = path.Join(trimmedBasePath, path.Join(segments...))
|
||||
return *u
|
||||
}
|
||||
|
||||
func (r *Request) tryThrottleWithInfo(ctx context.Context, retryInfo string) error {
|
||||
if r.rateLimiter == nil {
|
||||
return nil
|
||||
@@ -618,7 +537,7 @@ func (r *Request) tryThrottleWithInfo(ctx context.Context, retryInfo string) err
|
||||
// but we use a throttled logger to prevent spamming.
|
||||
globalThrottledLogger.Infof("%s", message)
|
||||
}
|
||||
metrics.RateLimiterLatency.Observe(ctx, r.verb, r.finalURLTemplate(), latency)
|
||||
metrics.RateLimiterLatency.Observe(ctx, r.verb, *r.URL(), latency)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -826,7 +745,7 @@ func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) {
|
||||
return nil, err
|
||||
}
|
||||
if r.body != nil {
|
||||
req.Body = io.NopCloser(r.body)
|
||||
req.Body = ioutil.NopCloser(r.body)
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
updateURLMetrics(ctx, r, resp, err)
|
||||
@@ -907,7 +826,7 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp
|
||||
// Metrics for total request latency
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
metrics.RequestLatency.Observe(ctx, r.verb, r.finalURLTemplate(), time.Since(start))
|
||||
metrics.RequestLatency.Observe(ctx, r.verb, *r.URL(), time.Since(start))
|
||||
}()
|
||||
|
||||
if r.err != nil {
|
||||
@@ -1018,7 +937,7 @@ func (r *Request) Do(ctx context.Context) Result {
|
||||
func (r *Request) DoRaw(ctx context.Context) ([]byte, error) {
|
||||
var result Result
|
||||
err := r.request(ctx, func(req *http.Request, resp *http.Response) {
|
||||
result.body, result.err = io.ReadAll(resp.Body)
|
||||
result.body, result.err = ioutil.ReadAll(resp.Body)
|
||||
glogBody("Response Body", result.body)
|
||||
if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent {
|
||||
result.err = r.transformUnstructuredResponseError(resp, req, result.body)
|
||||
@@ -1037,7 +956,7 @@ func (r *Request) DoRaw(ctx context.Context) ([]byte, error) {
|
||||
func (r *Request) transformResponse(resp *http.Response, req *http.Request) Result {
|
||||
var body []byte
|
||||
if resp.Body != nil {
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
switch err.(type) {
|
||||
case nil:
|
||||
body = data
|
||||
@@ -1179,7 +1098,7 @@ const maxUnstructuredResponseTextBytes = 2048
|
||||
// TODO: introduce transformation of generic http.Client.Do() errors that separates 4.
|
||||
func (r *Request) transformUnstructuredResponseError(resp *http.Response, req *http.Request, body []byte) error {
|
||||
if body == nil && resp.Body != nil {
|
||||
if data, err := io.ReadAll(&io.LimitedReader{R: resp.Body, N: maxUnstructuredResponseTextBytes}); err == nil {
|
||||
if data, err := ioutil.ReadAll(&io.LimitedReader{R: resp.Body, N: maxUnstructuredResponseTextBytes}); err == nil {
|
||||
body = data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -87,7 +88,7 @@ func TestRequestSetsHeaders(t *testing.T) {
|
||||
}
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusForbidden,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}, nil
|
||||
})
|
||||
config := defaultContentConfig()
|
||||
@@ -302,7 +303,7 @@ func TestRequestBody(t *testing.T) {
|
||||
}
|
||||
|
||||
// test error set when failing to read file
|
||||
f, err := os.CreateTemp("", "test")
|
||||
f, err := ioutil.TempFile("", "test")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create temp file")
|
||||
}
|
||||
@@ -337,206 +338,6 @@ func TestResultIntoWithNoBodyReturnsErr(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLTemplate(t *testing.T) {
|
||||
uri, _ := url.Parse("http://localhost/some/base/url/path")
|
||||
uriSingleSlash, _ := url.Parse("http://localhost/")
|
||||
testCases := []struct {
|
||||
Request *Request
|
||||
ExpectedFullURL string
|
||||
ExpectedFinalURL string
|
||||
}{
|
||||
{
|
||||
// non dynamic client
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("POST").
|
||||
Prefix("api", "v1").Resource("r1").Namespace("ns").Name("nm").Param("p0", "v0"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/api/v1/namespaces/ns/r1/nm?p0=v0",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/api/v1/namespaces/%7Bnamespace%7D/r1/%7Bname%7D?p0=%7Bvalue%7D",
|
||||
},
|
||||
{
|
||||
// non dynamic client with wrong api group
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("POST").
|
||||
Prefix("pre1", "v1").Resource("r1").Namespace("ns").Name("nm").Param("p0", "v0"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/pre1/v1/namespaces/ns/r1/nm?p0=v0",
|
||||
ExpectedFinalURL: "http://localhost/%7Bprefix%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with core group + namespace + resourceResource (with name)
|
||||
// /api/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/api/v1/namespaces/ns/r1/name1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/api/v1/namespaces/ns/r1/name1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/api/v1/namespaces/%7Bnamespace%7D/r1/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/g1/v1/namespaces/ns/r1/name1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/g1/v1/namespaces/ns/r1/name1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/g1/v1/namespaces/%7Bnamespace%7D/r1/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with core group + namespace + resourceResource (with NO name)
|
||||
// /api/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/api/v1/namespaces/ns/r1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/api/v1/namespaces/ns/r1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/api/v1/namespaces/%7Bnamespace%7D/r1",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with NO name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/g1/v1/namespaces/ns/r1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/g1/v1/namespaces/ns/r1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/g1/v1/namespaces/%7Bnamespace%7D/r1",
|
||||
},
|
||||
{
|
||||
// dynamic client with core group + resourceResource (with name)
|
||||
// /api/$RESOURCEVERSION/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/api/v1/r1/name1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/api/v1/r1/name1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/api/v1/r1/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + resourceResource (with name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/g1/v1/r1/name1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/g1/v1/r1/name1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/g1/v1/r1/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with name) + subresource
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME/$SUBRESOURCE
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces/finalize"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces/finalize",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bnamespace%7D/namespaces/%7Bname%7D/finalize",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bnamespace%7D/namespaces/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with NO name) + subresource
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%SUBRESOURCE
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/namespaces/finalize"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/namespaces/finalize",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bnamespace%7D/namespaces/finalize",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with NO name) + subresource
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%SUBRESOURCE
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/namespaces/status"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/namespaces/status",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bnamespace%7D/namespaces/status",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + namespace + resourceResource (with no name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/namespaces"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/namespaces",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bnamespace%7D/namespaces",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + resourceResource (with name) + subresource
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/finalize"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/finalize",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bname%7D/finalize",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + resourceResource (with name) + subresource
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces/status"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces/status",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bname%7D/status",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + resourceResource (with name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces/namespaces"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/namespaces",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with named group + resourceResource (with no name)
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/apis/namespaces/namespaces/namespaces"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/apis/namespaces/namespaces/namespaces",
|
||||
},
|
||||
{
|
||||
// dynamic client with wrong api group + namespace + resourceResource (with name) + subresource
|
||||
// /apis/$NAMEDGROUPNAME/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME/$SUBRESOURCE
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/pre1/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces/finalize"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/pre1/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces/finalize",
|
||||
ExpectedFinalURL: "http://localhost/%7Bprefix%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with core group + namespace + resourceResource (with name) where baseURL is a single /
|
||||
// /api/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uriSingleSlash, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/api/v1/namespaces/ns/r2/name1"),
|
||||
ExpectedFullURL: "http://localhost/api/v1/namespaces/ns/r2/name1",
|
||||
ExpectedFinalURL: "http://localhost/api/v1/namespaces/%7Bnamespace%7D/r2/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client with core group + namespace + resourceResource (with name) where baseURL is 'some/base/url/path'
|
||||
// /api/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME
|
||||
Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/api/v1/namespaces/ns/r3/name1"),
|
||||
ExpectedFullURL: "http://localhost/some/base/url/path/api/v1/namespaces/ns/r3/name1",
|
||||
ExpectedFinalURL: "http://localhost/some/base/url/path/api/v1/namespaces/%7Bnamespace%7D/r3/%7Bname%7D",
|
||||
},
|
||||
{
|
||||
// dynamic client where baseURL is a single /
|
||||
// /
|
||||
Request: NewRequestWithClient(uriSingleSlash, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/"),
|
||||
ExpectedFullURL: "http://localhost/",
|
||||
ExpectedFinalURL: "http://localhost/",
|
||||
},
|
||||
{
|
||||
// dynamic client where baseURL is a single /
|
||||
// /version
|
||||
Request: NewRequestWithClient(uriSingleSlash, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE").
|
||||
Prefix("/version"),
|
||||
ExpectedFullURL: "http://localhost/version",
|
||||
ExpectedFinalURL: "http://localhost/version",
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
r := testCase.Request
|
||||
full := r.URL()
|
||||
if full.String() != testCase.ExpectedFullURL {
|
||||
t.Errorf("%d: unexpected initial URL: %s %s", i, full, testCase.ExpectedFullURL)
|
||||
}
|
||||
actualURL := r.finalURLTemplate()
|
||||
actual := actualURL.String()
|
||||
if actual != testCase.ExpectedFinalURL {
|
||||
t.Errorf("%d: unexpected URL template: %s %s", i, actual, testCase.ExpectedFinalURL)
|
||||
}
|
||||
if r.URL().String() != full.String() {
|
||||
t.Errorf("%d, creating URL template changed request: %s -> %s", i, full.String(), r.URL().String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransformResponse(t *testing.T) {
|
||||
invalid := []byte("aaaaa")
|
||||
uri, _ := url.Parse("http://localhost")
|
||||
@@ -559,7 +360,7 @@ func TestTransformResponse(t *testing.T) {
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Header: http.Header{"Content-Type": []string{"application/json"}},
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Error: true,
|
||||
ErrFn: func(err error) bool {
|
||||
@@ -570,7 +371,7 @@ func TestTransformResponse(t *testing.T) {
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Header: http.Header{"Content-Type": []string{"text/any"}},
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Error: true,
|
||||
ErrFn: func(err error) bool {
|
||||
@@ -578,13 +379,13 @@ func TestTransformResponse(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{Response: &http.Response{StatusCode: http.StatusForbidden}, Error: true},
|
||||
{Response: &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader(invalid))}, Data: invalid},
|
||||
{Response: &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader(invalid))}, Data: invalid},
|
||||
{Response: &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(bytes.NewReader(invalid))}, Data: invalid},
|
||||
{Response: &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(bytes.NewReader(invalid))}, Data: invalid},
|
||||
}
|
||||
for i, test := range testCases {
|
||||
r := NewRequestWithClient(uri, "", defaultContentConfig(), nil)
|
||||
if test.Response.Body == nil {
|
||||
test.Response.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
test.Response.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
}
|
||||
result := r.transformResponse(test.Response, &http.Request{})
|
||||
response, created, err := result.body, result.statusCode == http.StatusCreated, result.err
|
||||
@@ -657,7 +458,7 @@ func TestTransformResponseNegotiate(t *testing.T) {
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Header: http.Header{"Content-Type": []string{"application/json"}},
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Called: true,
|
||||
ExpectContentType: "application/json",
|
||||
@@ -671,7 +472,7 @@ func TestTransformResponseNegotiate(t *testing.T) {
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Header: http.Header{"Content-Type": []string{"application/protobuf"}},
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Decoder: scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion),
|
||||
|
||||
@@ -701,7 +502,7 @@ func TestTransformResponseNegotiate(t *testing.T) {
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: http.Header{"Content-Type": []string{"text/any"}},
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Decoder: scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion),
|
||||
Called: true,
|
||||
@@ -712,7 +513,7 @@ func TestTransformResponseNegotiate(t *testing.T) {
|
||||
ContentType: "text/any",
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Decoder: scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion),
|
||||
Called: true,
|
||||
@@ -724,7 +525,7 @@ func TestTransformResponseNegotiate(t *testing.T) {
|
||||
Response: &http.Response{
|
||||
StatusCode: http.StatusNotFound,
|
||||
Header: http.Header{"Content-Type": []string{"application/unrecognized"}},
|
||||
Body: io.NopCloser(bytes.NewReader(invalid)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(invalid)),
|
||||
},
|
||||
Decoder: scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion),
|
||||
|
||||
@@ -748,7 +549,7 @@ func TestTransformResponseNegotiate(t *testing.T) {
|
||||
contentConfig.Negotiator = negotiator
|
||||
r := NewRequestWithClient(uri, "", contentConfig, nil)
|
||||
if test.Response.Body == nil {
|
||||
test.Response.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
test.Response.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
}
|
||||
result := r.transformResponse(test.Response, &http.Request{})
|
||||
_, err := result.body, result.err
|
||||
@@ -800,7 +601,7 @@ func TestTransformUnstructuredError(t *testing.T) {
|
||||
},
|
||||
Res: &http.Response{
|
||||
StatusCode: http.StatusConflict,
|
||||
Body: io.NopCloser(bytes.NewReader(nil)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(nil)),
|
||||
},
|
||||
ErrFn: apierrors.IsAlreadyExists,
|
||||
},
|
||||
@@ -812,7 +613,7 @@ func TestTransformUnstructuredError(t *testing.T) {
|
||||
},
|
||||
Res: &http.Response{
|
||||
StatusCode: http.StatusConflict,
|
||||
Body: io.NopCloser(bytes.NewReader(nil)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(nil)),
|
||||
},
|
||||
ErrFn: apierrors.IsConflict,
|
||||
},
|
||||
@@ -822,7 +623,7 @@ func TestTransformUnstructuredError(t *testing.T) {
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{
|
||||
StatusCode: http.StatusNotFound,
|
||||
Body: io.NopCloser(bytes.NewReader(nil)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(nil)),
|
||||
},
|
||||
ErrFn: apierrors.IsNotFound,
|
||||
},
|
||||
@@ -830,14 +631,14 @@ func TestTransformUnstructuredError(t *testing.T) {
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Body: io.NopCloser(bytes.NewReader(nil)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader(nil)),
|
||||
},
|
||||
ErrFn: apierrors.IsBadRequest,
|
||||
},
|
||||
{
|
||||
// status in response overrides transformed result
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","apiVersion":"v1","status":"Failure","code":404}`)))},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: ioutil.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","apiVersion":"v1","status":"Failure","code":404}`)))},
|
||||
ErrFn: apierrors.IsBadRequest,
|
||||
Transformed: &apierrors.StatusError{
|
||||
ErrStatus: metav1.Status{Status: metav1.StatusFailure, Code: http.StatusNotFound},
|
||||
@@ -846,20 +647,20 @@ func TestTransformUnstructuredError(t *testing.T) {
|
||||
{
|
||||
// successful status is ignored
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","apiVersion":"v1","status":"Success","code":404}`)))},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: ioutil.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","apiVersion":"v1","status":"Success","code":404}`)))},
|
||||
ErrFn: apierrors.IsBadRequest,
|
||||
},
|
||||
{
|
||||
// empty object does not change result
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewReader([]byte(`{}`)))},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: ioutil.NopCloser(bytes.NewReader([]byte(`{}`)))},
|
||||
ErrFn: apierrors.IsBadRequest,
|
||||
},
|
||||
{
|
||||
// we default apiVersion for backwards compatibility with old clients
|
||||
// TODO: potentially remove in 1.7
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","status":"Failure","code":404}`)))},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: ioutil.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","status":"Failure","code":404}`)))},
|
||||
ErrFn: apierrors.IsBadRequest,
|
||||
Transformed: &apierrors.StatusError{
|
||||
ErrStatus: metav1.Status{Status: metav1.StatusFailure, Code: http.StatusNotFound},
|
||||
@@ -868,7 +669,7 @@ func TestTransformUnstructuredError(t *testing.T) {
|
||||
{
|
||||
// we do not default kind
|
||||
Req: &http.Request{},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewReader([]byte(`{"status":"Failure","code":404}`)))},
|
||||
Res: &http.Response{StatusCode: http.StatusBadRequest, Body: ioutil.NopCloser(bytes.NewReader([]byte(`{"status":"Failure","code":404}`)))},
|
||||
ErrFn: apierrors.IsBadRequest,
|
||||
},
|
||||
}
|
||||
@@ -972,7 +773,7 @@ func TestRequestWatch(t *testing.T) {
|
||||
serverReturns: []responseErr{
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusForbidden,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}, err: nil},
|
||||
},
|
||||
attemptsExpected: 1,
|
||||
@@ -1015,7 +816,7 @@ func TestRequestWatch(t *testing.T) {
|
||||
serverReturns: []responseErr{
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusForbidden,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}, err: nil},
|
||||
},
|
||||
attemptsExpected: 1,
|
||||
@@ -1035,7 +836,7 @@ func TestRequestWatch(t *testing.T) {
|
||||
serverReturns: []responseErr{
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}, err: nil},
|
||||
},
|
||||
attemptsExpected: 1,
|
||||
@@ -1055,7 +856,7 @@ func TestRequestWatch(t *testing.T) {
|
||||
serverReturns: []responseErr{
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &metav1.Status{
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
Reason: metav1.StatusReasonUnauthorized,
|
||||
})))),
|
||||
@@ -1287,7 +1088,7 @@ func TestRequestStream(t *testing.T) {
|
||||
serverReturns: []responseErr{
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &metav1.Status{
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
Reason: metav1.StatusReasonUnauthorized,
|
||||
})))),
|
||||
@@ -1306,7 +1107,7 @@ func TestRequestStream(t *testing.T) {
|
||||
serverReturns: []responseErr{
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"a container name must be specified for pod kube-dns-v20-mz5cv, choose one of: [kubedns dnsmasq healthz]","reason":"BadRequest","code":400}`))),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"a container name must be specified for pod kube-dns-v20-mz5cv, choose one of: [kubedns dnsmasq healthz]","reason":"BadRequest","code":400}`))),
|
||||
}, err: nil},
|
||||
},
|
||||
attemptsExpected: 1,
|
||||
@@ -1387,7 +1188,7 @@ func TestRequestStream(t *testing.T) {
|
||||
{response: retryAfterResponse(), err: nil},
|
||||
{response: &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}, err: nil},
|
||||
},
|
||||
},
|
||||
@@ -1626,7 +1427,7 @@ func TestConnectionResetByPeerIsRetried(t *testing.T) {
|
||||
if count >= 3 {
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}, nil
|
||||
}
|
||||
return nil, &net.OpError{Err: syscall.ECONNRESET}
|
||||
@@ -1654,7 +1455,7 @@ func TestCheckRetryHandles429And5xx(t *testing.T) {
|
||||
count := 0
|
||||
ch := make(chan struct{})
|
||||
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
data, err := io.ReadAll(req.Body)
|
||||
data, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read request body: %v", err)
|
||||
}
|
||||
@@ -1806,7 +1607,7 @@ func TestDoRequestNewWayFile(t *testing.T) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
file, err := os.CreateTemp("", "foo")
|
||||
file, err := ioutil.TempFile("", "foo")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -1978,7 +1779,7 @@ func TestBody(t *testing.T) {
|
||||
obj := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
|
||||
bodyExpected, _ := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), obj)
|
||||
|
||||
f, err := os.CreateTemp("", "test_body")
|
||||
f, err := ioutil.TempFile("", "test_body")
|
||||
if err != nil {
|
||||
t.Fatalf("TempFile error: %v", err)
|
||||
}
|
||||
@@ -2648,7 +2449,7 @@ func TestRequestWithRetry(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "server returns retry-after response, request body is not io.Seeker, retry goes ahead",
|
||||
body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
serverReturns: responseErr{response: retryAfterResponse(), err: nil},
|
||||
errExpected: nil,
|
||||
transformFuncInvokedExpected: 1,
|
||||
@@ -2672,7 +2473,7 @@ func TestRequestWithRetry(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "server returns retryable err, request body is not io.Seek, retry goes ahead",
|
||||
body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||
body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
serverReturns: responseErr{response: nil, err: io.ErrUnexpectedEOF},
|
||||
errExpected: io.ErrUnexpectedEOF,
|
||||
transformFuncInvokedExpected: 0,
|
||||
@@ -2972,7 +2773,7 @@ func testRequestWithRetry(t *testing.T, key string, doFunc func(ctx context.Cont
|
||||
|
||||
resp := test.serverReturns[attempts].response
|
||||
if resp != nil {
|
||||
responseRecorder.delegated = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
responseRecorder.delegated = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
resp.Body = responseRecorder
|
||||
}
|
||||
return resp, test.serverReturns[attempts].err
|
||||
@@ -3253,7 +3054,7 @@ func testRetryWithRateLimiterBackoffAndMetrics(t *testing.T, key string, doFunc
|
||||
interceptor.Do()
|
||||
resp := test.serverReturns[attempts].response
|
||||
if resp != nil {
|
||||
resp.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
}
|
||||
return resp, test.serverReturns[attempts].err
|
||||
})
|
||||
@@ -3389,7 +3190,7 @@ func testWithRetryInvokeOrder(t *testing.T, key string, doFunc func(ctx context.
|
||||
interceptor.Do()
|
||||
resp := test.serverReturns[attempts].response
|
||||
if resp != nil {
|
||||
resp.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
}
|
||||
return resp, test.serverReturns[attempts].err
|
||||
})
|
||||
@@ -3564,7 +3365,7 @@ func testWithWrapPreviousError(t *testing.T, doFunc func(ctx context.Context, r
|
||||
|
||||
resp := test.serverReturns[attempts].response
|
||||
if resp != nil {
|
||||
resp.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
}
|
||||
return resp, test.serverReturns[attempts].err
|
||||
})
|
||||
@@ -3864,12 +3665,12 @@ func TestRequestBodyResetOrder(t *testing.T) {
|
||||
}()
|
||||
|
||||
// read the request body.
|
||||
io.ReadAll(req.Body)
|
||||
ioutil.ReadAll(req.Body)
|
||||
|
||||
// first attempt, we send a retry-after
|
||||
if attempts == 0 {
|
||||
resp := retryAfterResponse()
|
||||
respBodyTracker.ReadCloser = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
respBodyTracker.ReadCloser = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
resp.Body = respBodyTracker
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -108,13 +108,10 @@ func (c *Config) TransportConfig() (*transport.Config, error) {
|
||||
Groups: c.Impersonate.Groups,
|
||||
Extra: c.Impersonate.Extra,
|
||||
},
|
||||
Dial: c.Dial,
|
||||
Proxy: c.Proxy,
|
||||
}
|
||||
|
||||
if c.Dial != nil {
|
||||
conf.DialHolder = &transport.DialHolder{Dial: c.Dial}
|
||||
}
|
||||
|
||||
if c.ExecProvider != nil && c.AuthProvider != nil {
|
||||
return nil, errors.New("execProvider and authProvider cannot be used in combination")
|
||||
}
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
// TestTransportForThreadSafe is meant to be run with the race detector
|
||||
// to detect that the Transport generation for client-go is safe to
|
||||
// call from multiple goroutines.
|
||||
func TestTransportForThreadSafe(t *testing.T) {
|
||||
const (
|
||||
rootCACert = `-----BEGIN CERTIFICATE-----
|
||||
MIIC4DCCAcqgAwIBAgIBATALBgkqhkiG9w0BAQswIzEhMB8GA1UEAwwYMTAuMTMu
|
||||
MTI5LjEwNkAxNDIxMzU5MDU4MB4XDTE1MDExNTIxNTczN1oXDTE2MDExNTIxNTcz
|
||||
OFowIzEhMB8GA1UEAwwYMTAuMTMuMTI5LjEwNkAxNDIxMzU5MDU4MIIBIjANBgkq
|
||||
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunDRXGwsiYWGFDlWH6kjGun+PshDGeZX
|
||||
xtx9lUnL8pIRWH3wX6f13PO9sktaOWW0T0mlo6k2bMlSLlSZgG9H6og0W6gLS3vq
|
||||
s4VavZ6DbXIwemZG2vbRwsvR+t4G6Nbwelm6F8RFnA1Fwt428pavmNQ/wgYzo+T1
|
||||
1eS+HiN4ACnSoDSx3QRWcgBkB1g6VReofVjx63i0J+w8Q/41L9GUuLqquFxu6ZnH
|
||||
60vTB55lHgFiDLjA1FkEz2dGvGh/wtnFlRvjaPC54JH2K1mPYAUXTreoeJtLJKX0
|
||||
ycoiyB24+zGCniUmgIsmQWRPaOPircexCp1BOeze82BT1LCZNTVaxQIDAQABoyMw
|
||||
ITAOBgNVHQ8BAf8EBAMCAKQwDwYDVR0TAQH/BAUwAwEB/zALBgkqhkiG9w0BAQsD
|
||||
ggEBADMxsUuAFlsYDpF4fRCzXXwrhbtj4oQwcHpbu+rnOPHCZupiafzZpDu+rw4x
|
||||
YGPnCb594bRTQn4pAu3Ac18NbLD5pV3uioAkv8oPkgr8aUhXqiv7KdDiaWm6sbAL
|
||||
EHiXVBBAFvQws10HMqMoKtO8f1XDNAUkWduakR/U6yMgvOPwS7xl0eUTqyRB6zGb
|
||||
K55q2dejiFWaFqB/y78txzvz6UlOZKE44g2JAVoJVM6kGaxh33q8/FmrL4kuN3ut
|
||||
W+MmJCVDvd4eEqPwbp7146ZWTqpIJ8lvA6wuChtqV8lhAPka2hD/LMqY8iXNmfXD
|
||||
uml0obOEy+ON91k+SWTJ3ggmF/U=
|
||||
-----END CERTIFICATE-----`
|
||||
authPluginName = "auth-plugin-tr"
|
||||
)
|
||||
|
||||
err := RegisterAuthProviderPlugin(authPluginName, pluginAProvider)
|
||||
// the plugins are stored in a global variable that fails if the test
|
||||
// runs with the flag -count N, with N > 1
|
||||
if err != nil && !strings.Contains(err.Error(), "was registered twice") {
|
||||
t.Errorf("Unexpected error: failed to register pluginA: %v", err)
|
||||
}
|
||||
|
||||
configurations := []struct {
|
||||
name string
|
||||
config *Config
|
||||
}{
|
||||
{
|
||||
name: "simple config",
|
||||
config: &Config{
|
||||
Host: "localhost:8080",
|
||||
Username: "gopher",
|
||||
Password: "g0ph3r",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not cacheable config",
|
||||
config: &Config{
|
||||
Host: "localhost:8080",
|
||||
Username: "gopher",
|
||||
Password: "g0ph3r",
|
||||
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return nil, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with TLS config",
|
||||
config: &Config{
|
||||
Host: "localhost:8080",
|
||||
Username: "gopher",
|
||||
Password: "g0ph3r",
|
||||
TLSClientConfig: TLSClientConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with auth provider",
|
||||
config: &Config{
|
||||
Host: "localhost:8080",
|
||||
Username: "gopher",
|
||||
Password: "g0ph3r",
|
||||
TLSClientConfig: TLSClientConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
},
|
||||
AuthProvider: &clientcmdapi.AuthProviderConfig{
|
||||
Name: authPluginName,
|
||||
Config: map[string]string{"secret": "s3cr3t"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with exec provider",
|
||||
config: &Config{
|
||||
Host: "localhost:8080",
|
||||
Username: "gopher",
|
||||
Password: "g0ph3r",
|
||||
TLSClientConfig: TLSClientConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
},
|
||||
ExecProvider: &clientcmdapi.ExecConfig{
|
||||
Args: []string{"secret"},
|
||||
Env: []clientcmdapi.ExecEnvVar{{Name: "secret", Value: "s3cr3t"}},
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for _, tt := range configurations {
|
||||
tt := tt
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i := 1; i <= 50; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
_, err := TransportFor(tt.config)
|
||||
if err != nil {
|
||||
t.Errorf("Config: %s TransportFor() error = %v", tt.name, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -18,7 +18,7 @@ package versioned_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
@@ -70,7 +70,7 @@ func TestEncodeDecodeRoundTrip(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
rc := io.NopCloser(buf)
|
||||
rc := ioutil.NopCloser(buf)
|
||||
decoder := restclientwatch.NewDecoder(streaming.NewDecoder(rc, getDecoder()), getDecoder())
|
||||
event, obj, err := decoder.Decode()
|
||||
if err != nil {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -344,7 +345,7 @@ func readAndCloseResponseBody(resp *http.Response) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.ContentLength <= maxBodySlurpSize {
|
||||
io.Copy(io.Discard, &io.LimitedReader{R: resp.Body, N: maxBodySlurpSize})
|
||||
io.Copy(ioutil.Discard, &io.LimitedReader{R: resp.Body, N: maxBodySlurpSize})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@@ -45,7 +46,7 @@ import (
|
||||
)
|
||||
|
||||
func bytesBody(bodyBytes []byte) io.ReadCloser {
|
||||
return io.NopCloser(bytes.NewReader(bodyBytes))
|
||||
return ioutil.NopCloser(bytes.NewReader(bodyBytes))
|
||||
}
|
||||
|
||||
func defaultHeaders() http.Header {
|
||||
@@ -183,7 +184,7 @@ func fakeScaleClient(t *testing.T) (ScalesGetter, []schema.GroupResource) {
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
case "PUT":
|
||||
decoder := codecs.UniversalDeserializer()
|
||||
body, err := io.ReadAll(req.Body)
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,7 +201,7 @@ func fakeScaleClient(t *testing.T) (ScalesGetter, []schema.GroupResource) {
|
||||
}
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
case "PATCH":
|
||||
body, err := io.ReadAll(req.Body)
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ package auth
|
||||
// TODO: need a way to rotate Tokens. Therefore, need a way for client object to be reset when the authcfg is updated.
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
restclient "k8s.io/client-go/rest"
|
||||
@@ -89,7 +90,7 @@ func LoadFromFile(path string) (*Info, error) {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package auth_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
@@ -41,7 +42,7 @@ func TestLoadFromFile(t *testing.T) {
|
||||
}
|
||||
for _, loadAuthInfoTest := range loadAuthInfoTests {
|
||||
tt := loadAuthInfoTest
|
||||
aifile, err := os.CreateTemp("", "testAuthInfo")
|
||||
aifile, err := ioutil.TempFile("", "testAuthInfo")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
163
tools/cache/shared_informer.go
vendored
163
tools/cache/shared_informer.go
vendored
@@ -135,9 +135,7 @@ type SharedInformer interface {
|
||||
// AddEventHandler adds an event handler to the shared informer using the shared informer's resync
|
||||
// period. Events to a single handler are delivered sequentially, but there is no coordination
|
||||
// between different handlers.
|
||||
// It returns a registration handle for the handler that can be used to remove
|
||||
// the handler again.
|
||||
AddEventHandler(handler ResourceEventHandler) (ResourceEventHandlerRegistration, error)
|
||||
AddEventHandler(handler ResourceEventHandler)
|
||||
// AddEventHandlerWithResyncPeriod adds an event handler to the
|
||||
// shared informer with the requested resync period; zero means
|
||||
// this handler does not care about resyncs. The resync operation
|
||||
@@ -152,13 +150,7 @@ type SharedInformer interface {
|
||||
// between any two resyncs may be longer than the nominal period
|
||||
// because the implementation takes time to do work and there may
|
||||
// be competing load and scheduling noise.
|
||||
// It returns a registration handle for the handler that can be used to remove
|
||||
// the handler again and an error if the handler cannot be added.
|
||||
AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) (ResourceEventHandlerRegistration, error)
|
||||
// RemoveEventHandler removes a formerly added event handler given by
|
||||
// its registration handle.
|
||||
// This function is guaranteed to be idempotent, and thread-safe.
|
||||
RemoveEventHandler(handle ResourceEventHandlerRegistration) error
|
||||
AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration)
|
||||
// GetStore returns the informer's local cache as a Store.
|
||||
GetStore() Store
|
||||
// GetController is deprecated, it does nothing useful
|
||||
@@ -203,18 +195,8 @@ type SharedInformer interface {
|
||||
// transform before mutating it at all and returning the copy to prevent
|
||||
// data races.
|
||||
SetTransform(handler TransformFunc) error
|
||||
|
||||
// IsStopped reports whether the informer has already been stopped.
|
||||
// Adding event handlers to already stopped informers is not possible.
|
||||
// An informer already stopped will never be started again.
|
||||
IsStopped() bool
|
||||
}
|
||||
|
||||
// Opaque interface representing the registration of ResourceEventHandler for
|
||||
// a SharedInformer. Must be supplied back to the same SharedInformer's
|
||||
// `RemoveEventHandler` to unregister the handlers.
|
||||
type ResourceEventHandlerRegistration interface{}
|
||||
|
||||
// SharedIndexInformer provides add and get Indexers ability based on SharedInformer.
|
||||
type SharedIndexInformer interface {
|
||||
SharedInformer
|
||||
@@ -510,8 +492,8 @@ func (s *sharedIndexInformer) GetController() Controller {
|
||||
return &dummyController{informer: s}
|
||||
}
|
||||
|
||||
func (s *sharedIndexInformer) AddEventHandler(handler ResourceEventHandler) (ResourceEventHandlerRegistration, error) {
|
||||
return s.AddEventHandlerWithResyncPeriod(handler, s.defaultEventHandlerResyncPeriod)
|
||||
func (s *sharedIndexInformer) AddEventHandler(handler ResourceEventHandler) {
|
||||
s.AddEventHandlerWithResyncPeriod(handler, s.defaultEventHandlerResyncPeriod)
|
||||
}
|
||||
|
||||
func determineResyncPeriod(desired, check time.Duration) time.Duration {
|
||||
@@ -531,12 +513,13 @@ func determineResyncPeriod(desired, check time.Duration) time.Duration {
|
||||
|
||||
const minimumResyncPeriod = 1 * time.Second
|
||||
|
||||
func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) (ResourceEventHandlerRegistration, error) {
|
||||
func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) {
|
||||
s.startedLock.Lock()
|
||||
defer s.startedLock.Unlock()
|
||||
|
||||
if s.stopped {
|
||||
return nil, fmt.Errorf("handler %v was not added to shared informer because it has stopped already", handler)
|
||||
klog.V(2).Infof("Handler %v was not added to shared informer because it has stopped already", handler)
|
||||
return
|
||||
}
|
||||
|
||||
if resyncPeriod > 0 {
|
||||
@@ -562,7 +545,8 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv
|
||||
listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize)
|
||||
|
||||
if !s.started {
|
||||
return s.processor.addListener(listener), nil
|
||||
s.processor.addListener(listener)
|
||||
return
|
||||
}
|
||||
|
||||
// in order to safely join, we have to
|
||||
@@ -573,11 +557,10 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv
|
||||
s.blockDeltas.Lock()
|
||||
defer s.blockDeltas.Unlock()
|
||||
|
||||
handle := s.processor.addListener(listener)
|
||||
s.processor.addListener(listener)
|
||||
for _, item := range s.indexer.List() {
|
||||
listener.add(addNotification{newObj: item})
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
func (s *sharedIndexInformer) HandleDeltas(obj interface{}) error {
|
||||
@@ -627,26 +610,6 @@ func (s *sharedIndexInformer) OnDelete(old interface{}) {
|
||||
s.processor.distribute(deleteNotification{oldObj: old}, false)
|
||||
}
|
||||
|
||||
// IsStopped reports whether the informer has already been stopped
|
||||
func (s *sharedIndexInformer) IsStopped() bool {
|
||||
s.startedLock.Lock()
|
||||
defer s.startedLock.Unlock()
|
||||
return s.stopped
|
||||
}
|
||||
|
||||
func (s *sharedIndexInformer) RemoveEventHandler(handle ResourceEventHandlerRegistration) error {
|
||||
s.startedLock.Lock()
|
||||
defer s.startedLock.Unlock()
|
||||
|
||||
// in order to safely remove, we have to
|
||||
// 1. stop sending add/update/delete notifications
|
||||
// 2. remove and stop listener
|
||||
// 3. unblock
|
||||
s.blockDeltas.Lock()
|
||||
defer s.blockDeltas.Unlock()
|
||||
return s.processor.removeListener(handle)
|
||||
}
|
||||
|
||||
// sharedProcessor has a collection of processorListener and can
|
||||
// distribute a notification object to its listeners. There are two
|
||||
// kinds of distribute operations. The sync distributions go to a
|
||||
@@ -656,85 +619,39 @@ func (s *sharedIndexInformer) RemoveEventHandler(handle ResourceEventHandlerRegi
|
||||
type sharedProcessor struct {
|
||||
listenersStarted bool
|
||||
listenersLock sync.RWMutex
|
||||
// Map from listeners to whether or not they are currently syncing
|
||||
listeners map[*processorListener]bool
|
||||
clock clock.Clock
|
||||
wg wait.Group
|
||||
listeners []*processorListener
|
||||
syncingListeners []*processorListener
|
||||
clock clock.Clock
|
||||
wg wait.Group
|
||||
}
|
||||
|
||||
func (p *sharedProcessor) getListener(registration ResourceEventHandlerRegistration) *processorListener {
|
||||
p.listenersLock.RLock()
|
||||
defer p.listenersLock.RUnlock()
|
||||
|
||||
if p.listeners == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if result, ok := registration.(*processorListener); ok {
|
||||
if _, exists := p.listeners[result]; exists {
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *sharedProcessor) addListener(listener *processorListener) ResourceEventHandlerRegistration {
|
||||
func (p *sharedProcessor) addListener(listener *processorListener) {
|
||||
p.listenersLock.Lock()
|
||||
defer p.listenersLock.Unlock()
|
||||
|
||||
if p.listeners == nil {
|
||||
p.listeners = make(map[*processorListener]bool)
|
||||
}
|
||||
|
||||
p.listeners[listener] = true
|
||||
|
||||
p.addListenerLocked(listener)
|
||||
if p.listenersStarted {
|
||||
p.wg.Start(listener.run)
|
||||
p.wg.Start(listener.pop)
|
||||
}
|
||||
|
||||
return listener
|
||||
}
|
||||
|
||||
func (p *sharedProcessor) removeListener(handle ResourceEventHandlerRegistration) error {
|
||||
p.listenersLock.Lock()
|
||||
defer p.listenersLock.Unlock()
|
||||
|
||||
listener, ok := handle.(*processorListener)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid key type %t", handle)
|
||||
} else if p.listeners == nil {
|
||||
// No listeners are registered, do nothing
|
||||
return nil
|
||||
} else if _, exists := p.listeners[listener]; !exists {
|
||||
// Listener is not registered, just do nothing
|
||||
return nil
|
||||
}
|
||||
|
||||
delete(p.listeners, listener)
|
||||
|
||||
if p.listenersStarted {
|
||||
close(listener.addCh)
|
||||
}
|
||||
|
||||
return nil
|
||||
func (p *sharedProcessor) addListenerLocked(listener *processorListener) {
|
||||
p.listeners = append(p.listeners, listener)
|
||||
p.syncingListeners = append(p.syncingListeners, listener)
|
||||
}
|
||||
|
||||
func (p *sharedProcessor) distribute(obj interface{}, sync bool) {
|
||||
p.listenersLock.RLock()
|
||||
defer p.listenersLock.RUnlock()
|
||||
|
||||
for listener, isSyncing := range p.listeners {
|
||||
switch {
|
||||
case !sync:
|
||||
// non-sync messages are delivered to every listener
|
||||
if sync {
|
||||
for _, listener := range p.syncingListeners {
|
||||
listener.add(obj)
|
||||
case isSyncing:
|
||||
// sync messages are delivered to every syncing listenter
|
||||
}
|
||||
} else {
|
||||
for _, listener := range p.listeners {
|
||||
listener.add(obj)
|
||||
default:
|
||||
// skipping a sync obj for a non-syncing listener
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,27 +660,18 @@ func (p *sharedProcessor) run(stopCh <-chan struct{}) {
|
||||
func() {
|
||||
p.listenersLock.RLock()
|
||||
defer p.listenersLock.RUnlock()
|
||||
for listener := range p.listeners {
|
||||
for _, listener := range p.listeners {
|
||||
p.wg.Start(listener.run)
|
||||
p.wg.Start(listener.pop)
|
||||
}
|
||||
p.listenersStarted = true
|
||||
}()
|
||||
<-stopCh
|
||||
|
||||
p.listenersLock.Lock()
|
||||
defer p.listenersLock.Unlock()
|
||||
for listener := range p.listeners {
|
||||
p.listenersLock.RLock()
|
||||
defer p.listenersLock.RUnlock()
|
||||
for _, listener := range p.listeners {
|
||||
close(listener.addCh) // Tell .pop() to stop. .pop() will tell .run() to stop
|
||||
}
|
||||
|
||||
// Wipe out list of listeners since they are now closed
|
||||
// (processorListener cannot be re-used)
|
||||
p.listeners = nil
|
||||
|
||||
// Reset to false since no listeners are running
|
||||
p.listenersStarted = false
|
||||
|
||||
p.wg.Wait() // Wait for all .pop() and .run() to stop
|
||||
}
|
||||
|
||||
@@ -773,16 +681,16 @@ func (p *sharedProcessor) shouldResync() bool {
|
||||
p.listenersLock.Lock()
|
||||
defer p.listenersLock.Unlock()
|
||||
|
||||
p.syncingListeners = []*processorListener{}
|
||||
|
||||
resyncNeeded := false
|
||||
now := p.clock.Now()
|
||||
for listener := range p.listeners {
|
||||
for _, listener := range p.listeners {
|
||||
// need to loop through all the listeners to see if they need to resync so we can prepare any
|
||||
// listeners that are going to be resyncing.
|
||||
shouldResync := listener.shouldResync(now)
|
||||
p.listeners[listener] = shouldResync
|
||||
|
||||
if shouldResync {
|
||||
if listener.shouldResync(now) {
|
||||
resyncNeeded = true
|
||||
p.syncingListeners = append(p.syncingListeners, listener)
|
||||
listener.determineNextResync(now)
|
||||
}
|
||||
}
|
||||
@@ -793,9 +701,8 @@ func (p *sharedProcessor) resyncCheckPeriodChanged(resyncCheckPeriod time.Durati
|
||||
p.listenersLock.RLock()
|
||||
defer p.listenersLock.RUnlock()
|
||||
|
||||
for listener := range p.listeners {
|
||||
resyncPeriod := determineResyncPeriod(
|
||||
listener.requestedResyncPeriod, resyncCheckPeriod)
|
||||
for _, listener := range p.listeners {
|
||||
resyncPeriod := determineResyncPeriod(listener.requestedResyncPeriod, resyncCheckPeriod)
|
||||
listener.setResyncPeriod(resyncPeriod)
|
||||
}
|
||||
}
|
||||
|
||||
577
tools/cache/shared_informer_test.go
vendored
577
tools/cache/shared_informer_test.go
vendored
@@ -17,10 +17,7 @@ limitations under the License.
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -99,25 +96,6 @@ func (l *testListener) satisfiedExpectations() bool {
|
||||
return sets.NewString(l.receivedItemNames...).Equal(l.expectedItemNames)
|
||||
}
|
||||
|
||||
func eventHandlerCount(i SharedInformer) int {
|
||||
s := i.(*sharedIndexInformer)
|
||||
s.startedLock.Lock()
|
||||
defer s.startedLock.Unlock()
|
||||
return len(s.processor.listeners)
|
||||
}
|
||||
|
||||
func isStarted(i SharedInformer) bool {
|
||||
s := i.(*sharedIndexInformer)
|
||||
s.startedLock.Lock()
|
||||
defer s.startedLock.Unlock()
|
||||
return s.started
|
||||
}
|
||||
|
||||
func isRegistered(i SharedInformer, h ResourceEventHandlerRegistration) bool {
|
||||
s := i.(*sharedIndexInformer)
|
||||
return s.processor.getListener(h) != nil
|
||||
}
|
||||
|
||||
func TestListenerResyncPeriods(t *testing.T) {
|
||||
// source simulates an apiserver object endpoint.
|
||||
source := fcache.NewFakeControllerSource()
|
||||
@@ -211,7 +189,6 @@ func TestResyncCheckPeriod(t *testing.T) {
|
||||
|
||||
// create the shared informer and resync every 12 hours
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 12*time.Hour).(*sharedIndexInformer)
|
||||
gl := informer.processor.getListener
|
||||
|
||||
clock := testingclock.NewFakeClock(time.Now())
|
||||
informer.clock = clock
|
||||
@@ -219,60 +196,59 @@ func TestResyncCheckPeriod(t *testing.T) {
|
||||
|
||||
// listener 1, never resync
|
||||
listener1 := newTestListener("listener1", 0)
|
||||
handler1, _ := informer.AddEventHandlerWithResyncPeriod(listener1, listener1.resyncPeriod)
|
||||
|
||||
informer.AddEventHandlerWithResyncPeriod(listener1, listener1.resyncPeriod)
|
||||
if e, a := 12*time.Hour, informer.resyncCheckPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := time.Duration(0), gl(handler1).resyncPeriod; e != a {
|
||||
if e, a := time.Duration(0), informer.processor.listeners[0].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
// listener 2, resync every minute
|
||||
listener2 := newTestListener("listener2", 1*time.Minute)
|
||||
handler2, _ := informer.AddEventHandlerWithResyncPeriod(listener2, listener2.resyncPeriod)
|
||||
informer.AddEventHandlerWithResyncPeriod(listener2, listener2.resyncPeriod)
|
||||
if e, a := 1*time.Minute, informer.resyncCheckPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := time.Duration(0), gl(handler1).resyncPeriod; e != a {
|
||||
if e, a := time.Duration(0), informer.processor.listeners[0].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := 1*time.Minute, gl(handler2).resyncPeriod; e != a {
|
||||
if e, a := 1*time.Minute, informer.processor.listeners[1].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
// listener 3, resync every 55 seconds
|
||||
listener3 := newTestListener("listener3", 55*time.Second)
|
||||
handler3, _ := informer.AddEventHandlerWithResyncPeriod(listener3, listener3.resyncPeriod)
|
||||
informer.AddEventHandlerWithResyncPeriod(listener3, listener3.resyncPeriod)
|
||||
if e, a := 55*time.Second, informer.resyncCheckPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := time.Duration(0), gl(handler1).resyncPeriod; e != a {
|
||||
if e, a := time.Duration(0), informer.processor.listeners[0].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := 1*time.Minute, gl(handler2).resyncPeriod; e != a {
|
||||
if e, a := 1*time.Minute, informer.processor.listeners[1].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := 55*time.Second, gl(handler3).resyncPeriod; e != a {
|
||||
if e, a := 55*time.Second, informer.processor.listeners[2].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
// listener 4, resync every 5 seconds
|
||||
listener4 := newTestListener("listener4", 5*time.Second)
|
||||
handler4, _ := informer.AddEventHandlerWithResyncPeriod(listener4, listener4.resyncPeriod)
|
||||
informer.AddEventHandlerWithResyncPeriod(listener4, listener4.resyncPeriod)
|
||||
if e, a := 5*time.Second, informer.resyncCheckPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := time.Duration(0), gl(handler1).resyncPeriod; e != a {
|
||||
if e, a := time.Duration(0), informer.processor.listeners[0].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := 1*time.Minute, gl(handler2).resyncPeriod; e != a {
|
||||
if e, a := 1*time.Minute, informer.processor.listeners[1].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := 55*time.Second, gl(handler3).resyncPeriod; e != a {
|
||||
if e, a := 55*time.Second, informer.processor.listeners[2].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
if e, a := 5*time.Second, gl(handler4).resyncPeriod; e != a {
|
||||
if e, a := 5*time.Second, informer.processor.listeners[3].resyncPeriod; e != a {
|
||||
t.Errorf("expected %d, got %d", e, a)
|
||||
}
|
||||
}
|
||||
@@ -414,528 +390,3 @@ func TestSharedInformerTransformer(t *testing.T) {
|
||||
t.Errorf("%s: expected %v, got %v", listenerTransformer.name, listenerTransformer.expectedItemNames, listenerTransformer.receivedItemNames)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedInformerRemoveHandler(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second)
|
||||
|
||||
handler1 := &ResourceEventHandlerFuncs{}
|
||||
handle1, err := informer.AddEventHandler(handler1)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler1: %s", err)
|
||||
return
|
||||
}
|
||||
handler2 := &ResourceEventHandlerFuncs{}
|
||||
handle2, err := informer.AddEventHandler(handler2)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler2: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if eventHandlerCount(informer) != 2 {
|
||||
t.Errorf("informer has %d registered handler, instead of 2", eventHandlerCount(informer))
|
||||
}
|
||||
|
||||
if err := informer.RemoveEventHandler(handle2); err != nil {
|
||||
t.Errorf("removing of second pointer handler failed: %s", err)
|
||||
}
|
||||
if eventHandlerCount(informer) != 1 {
|
||||
t.Errorf("after removing handler informer has %d registered handler(s), instead of 1", eventHandlerCount(informer))
|
||||
}
|
||||
|
||||
if err := informer.RemoveEventHandler(handle1); err != nil {
|
||||
t.Errorf("removing of first pointer handler failed: %s", err)
|
||||
}
|
||||
if eventHandlerCount(informer) != 0 {
|
||||
t.Errorf("informer still has registered handlers after removing both handlers")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedInformerRemoveForeignHandler(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
|
||||
source2 := fcache.NewFakeControllerSource()
|
||||
source2.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer2 := NewSharedInformer(source2, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
|
||||
handler1 := &ResourceEventHandlerFuncs{}
|
||||
handle1, err := informer.AddEventHandler(handler1)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler1: %s", err)
|
||||
return
|
||||
}
|
||||
handler2 := &ResourceEventHandlerFuncs{}
|
||||
handle2, err := informer.AddEventHandler(handler2)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler2: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if eventHandlerCount(informer) != 2 {
|
||||
t.Errorf("informer has %d registered handler, instead of 2", eventHandlerCount(informer))
|
||||
}
|
||||
if eventHandlerCount(informer2) != 0 {
|
||||
t.Errorf("informer2 has %d registered handler, instead of 0", eventHandlerCount(informer2))
|
||||
}
|
||||
|
||||
// remove handle at foreign informer
|
||||
if isRegistered(informer2, handle1) {
|
||||
t.Errorf("handle1 registered for informer2")
|
||||
}
|
||||
if isRegistered(informer2, handle2) {
|
||||
t.Errorf("handle2 registered for informer2")
|
||||
}
|
||||
if err := informer2.RemoveEventHandler(handle1); err != nil {
|
||||
t.Errorf("removing of second pointer handler failed: %s", err)
|
||||
}
|
||||
if eventHandlerCount(informer) != 2 {
|
||||
t.Errorf("informer has %d registered handler, instead of 2", eventHandlerCount(informer))
|
||||
}
|
||||
if eventHandlerCount(informer2) != 0 {
|
||||
t.Errorf("informer2 has %d registered handler, instead of 0", eventHandlerCount(informer2))
|
||||
}
|
||||
if !isRegistered(informer, handle1) {
|
||||
t.Errorf("handle1 not registered anymore for informer")
|
||||
}
|
||||
if !isRegistered(informer, handle2) {
|
||||
t.Errorf("handle2 not registered anymore for informer")
|
||||
}
|
||||
|
||||
if eventHandlerCount(informer) != 2 {
|
||||
t.Errorf("informer has %d registered handler, instead of 2", eventHandlerCount(informer))
|
||||
}
|
||||
if eventHandlerCount(informer2) != 0 {
|
||||
t.Errorf("informer2 has %d registered handler, instead of 0", eventHandlerCount(informer2))
|
||||
}
|
||||
if !isRegistered(informer, handle1) {
|
||||
t.Errorf("handle1 not registered anymore for informer")
|
||||
}
|
||||
if !isRegistered(informer, handle2) {
|
||||
t.Errorf("handle2 not registered anymore for informer")
|
||||
}
|
||||
|
||||
if err := informer.RemoveEventHandler(handle2); err != nil {
|
||||
t.Errorf("removing of second pointer handler failed: %s", err)
|
||||
}
|
||||
if eventHandlerCount(informer) != 1 {
|
||||
t.Errorf("after removing handler informer has %d registered handler(s), instead of 1", eventHandlerCount(informer))
|
||||
}
|
||||
|
||||
if err := informer.RemoveEventHandler(handle1); err != nil {
|
||||
t.Errorf("removing of first pointer handler failed: %s", err)
|
||||
}
|
||||
if eventHandlerCount(informer) != 0 {
|
||||
t.Errorf("informer still has registered handlers after removing both handlers")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedInformerMultipleRegistration(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
|
||||
handler1 := &ResourceEventHandlerFuncs{}
|
||||
reg1, err := informer.AddEventHandler(handler1)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler for the first time: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !isRegistered(informer, reg1) {
|
||||
t.Errorf("handle1 is not active after successful registration")
|
||||
return
|
||||
}
|
||||
|
||||
reg2, err := informer.AddEventHandler(handler1)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler for the second: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !isRegistered(informer, reg2) {
|
||||
t.Errorf("handle2 is not active after successful registration")
|
||||
return
|
||||
}
|
||||
|
||||
if eventHandlerCount(informer) != 2 {
|
||||
t.Errorf("informer has %d registered handler(s), instead of 2", eventHandlerCount(informer))
|
||||
}
|
||||
|
||||
if err := informer.RemoveEventHandler(reg1); err != nil {
|
||||
t.Errorf("removing of duplicate handler registration failed: %s", err)
|
||||
}
|
||||
|
||||
if isRegistered(informer, reg1) {
|
||||
t.Errorf("handle1 is still active after successful remove")
|
||||
return
|
||||
}
|
||||
if !isRegistered(informer, reg2) {
|
||||
t.Errorf("handle2 is not active after removing handle1")
|
||||
return
|
||||
}
|
||||
|
||||
if eventHandlerCount(informer) != 1 {
|
||||
if eventHandlerCount(informer) == 0 {
|
||||
t.Errorf("informer has no registered handler anymore after removal of duplicate registrations")
|
||||
} else {
|
||||
t.Errorf("informer has unexpected number (%d) of handlers after removal of duplicate handler registration", eventHandlerCount(informer))
|
||||
}
|
||||
}
|
||||
|
||||
if err := informer.RemoveEventHandler(reg2); err != nil {
|
||||
t.Errorf("removing of second handler registration failed: %s", err)
|
||||
}
|
||||
|
||||
if isRegistered(informer, reg2) {
|
||||
t.Errorf("handle2 is still active after successful remove")
|
||||
return
|
||||
}
|
||||
|
||||
if eventHandlerCount(informer) != 0 {
|
||||
t.Errorf("informer has unexpected number (%d) of handlers after removal of second handler registrations", eventHandlerCount(informer))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovingRemovedSharedInformer(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
handler := &ResourceEventHandlerFuncs{}
|
||||
reg, err := informer.AddEventHandler(handler)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler for the first time: %s", err)
|
||||
return
|
||||
}
|
||||
if err := informer.RemoveEventHandler(reg); err != nil {
|
||||
t.Errorf("removing of handler registration failed: %s", err)
|
||||
return
|
||||
}
|
||||
if isRegistered(informer, reg) {
|
||||
t.Errorf("handle is still active after successful remove")
|
||||
return
|
||||
}
|
||||
if err := informer.RemoveEventHandler(reg); err != nil {
|
||||
t.Errorf("removing of already removed registration yields unexpected error: %s", err)
|
||||
}
|
||||
if isRegistered(informer, reg) {
|
||||
t.Errorf("handle is still active after second remove")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Shows that many concurrent goroutines can be manipulating shared informer
|
||||
// listeners without tripping it up. There are not really many assertions in this
|
||||
// test. Meant to be run with -race to find race conditions
|
||||
func TestSharedInformerHandlerAbuse(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
informerCtx, informerCancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
informer.Run(informerCtx.Done())
|
||||
cancel()
|
||||
}()
|
||||
|
||||
worker := func() {
|
||||
// Keep adding and removing handler
|
||||
// Make sure no duplicate events?
|
||||
funcs := ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {},
|
||||
UpdateFunc: func(oldObj, newObj interface{}) {},
|
||||
DeleteFunc: func(obj interface{}) {},
|
||||
}
|
||||
handles := []ResourceEventHandlerRegistration{}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
switch rand.Intn(2) {
|
||||
case 0:
|
||||
// Register handler again
|
||||
reg, err := informer.AddEventHandlerWithResyncPeriod(funcs, 1*time.Second)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "stopped already") {
|
||||
// test is over
|
||||
return
|
||||
}
|
||||
t.Errorf("failed to add handler: %v", err)
|
||||
return
|
||||
}
|
||||
handles = append(handles, reg)
|
||||
case 1:
|
||||
// Remove a random handler
|
||||
if len(handles) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
idx := rand.Intn(len(handles))
|
||||
err := informer.RemoveEventHandler(handles[idx])
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "stopped already") {
|
||||
// test is over
|
||||
return
|
||||
}
|
||||
t.Errorf("failed to remove handler: %v", err)
|
||||
return
|
||||
}
|
||||
handles = append(handles[:idx], handles[idx+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
worker()
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
objs := []*v1.Pod{}
|
||||
|
||||
// While workers run, randomly create events for the informer
|
||||
for i := 0; i < 10000; i++ {
|
||||
if len(objs) == 0 {
|
||||
// Make sure there is always an object
|
||||
obj := &v1.Pod{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod" + strconv.Itoa(i),
|
||||
}}
|
||||
objs = append(objs, obj)
|
||||
|
||||
// deep copy before adding since the Modify function mutates the obj
|
||||
source.Add(obj.DeepCopy())
|
||||
}
|
||||
|
||||
switch rand.Intn(3) {
|
||||
case 0:
|
||||
// Add Object
|
||||
obj := &v1.Pod{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod" + strconv.Itoa(i),
|
||||
}}
|
||||
objs = append(objs, obj)
|
||||
source.Add(obj.DeepCopy())
|
||||
case 1:
|
||||
// Update Object
|
||||
idx := rand.Intn(len(objs))
|
||||
source.Modify(objs[idx].DeepCopy())
|
||||
|
||||
case 2:
|
||||
// Remove Object
|
||||
idx := rand.Intn(len(objs))
|
||||
source.Delete(objs[idx].DeepCopy())
|
||||
objs = append(objs[:idx], objs[idx+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
// sotp informer which stops workers. stopping informer first to exercise
|
||||
// contention for informer while it is closing
|
||||
informerCancel()
|
||||
|
||||
// wait for workers to finish since they may throw errors
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestStateSharedInformer(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
listener := newTestListener("listener", 0, "pod1")
|
||||
informer.AddEventHandlerWithResyncPeriod(listener, listener.resyncPeriod)
|
||||
|
||||
if isStarted(informer) {
|
||||
t.Errorf("informer already started after creation")
|
||||
return
|
||||
}
|
||||
if informer.IsStopped() {
|
||||
t.Errorf("informer already stopped after creation")
|
||||
return
|
||||
}
|
||||
stop := make(chan struct{})
|
||||
go informer.Run(stop)
|
||||
if !listener.ok() {
|
||||
t.Errorf("informer did not report initial objects")
|
||||
close(stop)
|
||||
return
|
||||
}
|
||||
|
||||
if !isStarted(informer) {
|
||||
t.Errorf("informer does not report to be started although handling events")
|
||||
close(stop)
|
||||
return
|
||||
}
|
||||
if informer.IsStopped() {
|
||||
t.Errorf("informer reports to be stopped although stop channel not closed")
|
||||
close(stop)
|
||||
return
|
||||
}
|
||||
|
||||
close(stop)
|
||||
fmt.Println("sleeping")
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
if !informer.IsStopped() {
|
||||
t.Errorf("informer reports not to be stopped although stop channel closed")
|
||||
return
|
||||
}
|
||||
if !isStarted(informer) {
|
||||
t.Errorf("informer reports not to be started after it has been started and stopped")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddOnStoppedSharedInformer(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
listener := newTestListener("listener", 0, "pod1")
|
||||
stop := make(chan struct{})
|
||||
go informer.Run(stop)
|
||||
close(stop)
|
||||
|
||||
err := wait.PollImmediate(100*time.Millisecond, 2*time.Second, func() (bool, error) {
|
||||
if informer.IsStopped() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("informer reports not to be stopped although stop channel closed")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = informer.AddEventHandlerWithResyncPeriod(listener, listener.resyncPeriod)
|
||||
if err == nil {
|
||||
t.Errorf("stopped informer did not reject add handler")
|
||||
return
|
||||
}
|
||||
if !strings.HasSuffix(err.Error(), "was not added to shared informer because it has stopped already") {
|
||||
t.Errorf("adding handler to a stopped informer yields unexpected error: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOnStoppedSharedInformer(t *testing.T) {
|
||||
source := fcache.NewFakeControllerSource()
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
|
||||
listener := newTestListener("listener", 0, "pod1")
|
||||
handle, err := informer.AddEventHandlerWithResyncPeriod(listener, listener.resyncPeriod)
|
||||
if err != nil {
|
||||
t.Errorf("informer did not add handler: %s", err)
|
||||
return
|
||||
}
|
||||
stop := make(chan struct{})
|
||||
go informer.Run(stop)
|
||||
close(stop)
|
||||
fmt.Println("sleeping")
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
if !informer.IsStopped() {
|
||||
t.Errorf("informer reports not to be stopped although stop channel closed")
|
||||
return
|
||||
}
|
||||
err = informer.RemoveEventHandler(handle)
|
||||
if err != nil {
|
||||
t.Errorf("informer does not remove handler on stopped informer")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveWhileActive(t *testing.T) {
|
||||
// source simulates an apiserver object endpoint.
|
||||
source := fcache.NewFakeControllerSource()
|
||||
|
||||
// create the shared informer and resync every 12 hours
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 0).(*sharedIndexInformer)
|
||||
|
||||
listener := newTestListener("listener", 0, "pod1")
|
||||
handle, _ := informer.AddEventHandler(listener)
|
||||
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
|
||||
go informer.Run(stop)
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
if !listener.ok() {
|
||||
t.Errorf("event did not occur")
|
||||
return
|
||||
}
|
||||
|
||||
informer.RemoveEventHandler(handle)
|
||||
|
||||
if isRegistered(informer, handle) {
|
||||
t.Errorf("handle is still active after successful remove")
|
||||
return
|
||||
}
|
||||
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod2"}})
|
||||
|
||||
if !listener.ok() {
|
||||
t.Errorf("unexpected event occurred")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddWhileActive(t *testing.T) {
|
||||
// source simulates an apiserver object endpoint.
|
||||
source := fcache.NewFakeControllerSource()
|
||||
|
||||
// create the shared informer and resync every 12 hours
|
||||
informer := NewSharedInformer(source, &v1.Pod{}, 0).(*sharedIndexInformer)
|
||||
listener1 := newTestListener("originalListener", 0, "pod1")
|
||||
listener2 := newTestListener("originalListener", 0, "pod1", "pod2")
|
||||
handle1, _ := informer.AddEventHandler(listener1)
|
||||
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
|
||||
go informer.Run(stop)
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod1"}})
|
||||
|
||||
if !listener1.ok() {
|
||||
t.Errorf("events on listener1 did not occur")
|
||||
return
|
||||
}
|
||||
|
||||
handle2, _ := informer.AddEventHandler(listener2)
|
||||
source.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "pod2"}})
|
||||
|
||||
if !listener2.ok() {
|
||||
t.Errorf("event on listener2 did not occur")
|
||||
return
|
||||
}
|
||||
|
||||
if !isRegistered(informer, handle1) {
|
||||
t.Errorf("handle1 is not active")
|
||||
return
|
||||
}
|
||||
if !isRegistered(informer, handle2) {
|
||||
t.Errorf("handle2 is not active")
|
||||
return
|
||||
}
|
||||
|
||||
listener1.expectedItemNames = listener2.expectedItemNames
|
||||
if !listener1.ok() {
|
||||
t.Errorf("events on listener1 did not occur")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -151,7 +152,7 @@ func FlattenContent(path *string, contents *[]byte, baseDir string) error {
|
||||
|
||||
var err error
|
||||
absPath := ResolvePath(*path, baseDir)
|
||||
*contents, err = os.ReadFile(absPath)
|
||||
*contents, err = ioutil.ReadFile(absPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
@@ -26,13 +27,13 @@ import (
|
||||
)
|
||||
|
||||
func newMergedConfig(certFile, certContent, keyFile, keyContent, caFile, caContent string, t *testing.T) Config {
|
||||
if err := os.WriteFile(certFile, []byte(certContent), 0644); err != nil {
|
||||
if err := ioutil.WriteFile(certFile, []byte(certContent), 0644); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(keyFile, []byte(keyContent), 0600); err != nil {
|
||||
if err := ioutil.WriteFile(keyFile, []byte(keyContent), 0600); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(caFile, []byte(caContent), 0644); err != nil {
|
||||
if err := ioutil.WriteFile(caFile, []byte(caContent), 0644); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
@@ -51,11 +52,11 @@ func newMergedConfig(certFile, certContent, keyFile, keyContent, caFile, caConte
|
||||
}
|
||||
|
||||
func TestMinifySuccess(t *testing.T) {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
|
||||
@@ -87,11 +88,11 @@ func TestMinifySuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMinifyMissingContext(t *testing.T) {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
|
||||
@@ -105,11 +106,11 @@ func TestMinifyMissingContext(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMinifyMissingCluster(t *testing.T) {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
|
||||
@@ -123,11 +124,11 @@ func TestMinifyMissingCluster(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMinifyMissingAuthInfo(t *testing.T) {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t)
|
||||
@@ -141,11 +142,11 @@ func TestMinifyMissingAuthInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFlattenSuccess(t *testing.T) {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
certData := "cert"
|
||||
@@ -206,11 +207,11 @@ func TestFlattenSuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func Example_minifyAndShorten() {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
certData := "cert"
|
||||
@@ -246,11 +247,11 @@ func Example_minifyAndShorten() {
|
||||
}
|
||||
|
||||
func TestShortenSuccess(t *testing.T) {
|
||||
certFile, _ := os.CreateTemp("", "")
|
||||
certFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(certFile.Name())
|
||||
keyFile, _ := os.CreateTemp("", "")
|
||||
keyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(keyFile.Name())
|
||||
caFile, _ := os.CreateTemp("", "")
|
||||
caFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(caFile.Name())
|
||||
|
||||
certData := "cert"
|
||||
|
||||
@@ -93,11 +93,6 @@ type Cluster struct {
|
||||
// attach, port forward).
|
||||
// +optional
|
||||
ProxyURL string `json:"proxy-url,omitempty"`
|
||||
// DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful
|
||||
// to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on
|
||||
// compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296.
|
||||
// +optional
|
||||
DisableCompression bool `json:"disable-compression,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
// +optional
|
||||
Extensions map[string]runtime.Object `json:"extensions,omitempty"`
|
||||
|
||||
@@ -46,12 +46,10 @@ func Example_ofOptionsConfig() {
|
||||
Server: "https://alfa.org:8080",
|
||||
InsecureSkipTLSVerify: true,
|
||||
CertificateAuthority: "path/to/my/cert-ca-filename",
|
||||
DisableCompression: true,
|
||||
}
|
||||
defaultConfig.Clusters["bravo"] = &Cluster{
|
||||
Server: "https://bravo.org:8080",
|
||||
InsecureSkipTLSVerify: false,
|
||||
DisableCompression: false,
|
||||
}
|
||||
defaultConfig.AuthInfos["white-mage-via-cert"] = &AuthInfo{
|
||||
ClientCertificate: "path/to/my/client-cert-filename",
|
||||
@@ -96,7 +94,6 @@ func Example_ofOptionsConfig() {
|
||||
// alfa:
|
||||
// LocationOfOrigin: ""
|
||||
// certificate-authority: path/to/my/cert-ca-filename
|
||||
// disable-compression: true
|
||||
// insecure-skip-tls-verify: true
|
||||
// server: https://alfa.org:8080
|
||||
// bravo:
|
||||
|
||||
@@ -86,11 +86,6 @@ type Cluster struct {
|
||||
// attach, port forward).
|
||||
// +optional
|
||||
ProxyURL string `json:"proxy-url,omitempty"`
|
||||
// DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful
|
||||
// to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on
|
||||
// compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296.
|
||||
// +optional
|
||||
DisableCompression bool `json:"disable-compression,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
// +optional
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
|
||||
@@ -257,7 +257,6 @@ func autoConvert_v1_Cluster_To_api_Cluster(in *Cluster, out *api.Cluster, s conv
|
||||
out.CertificateAuthority = in.CertificateAuthority
|
||||
out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData))
|
||||
out.ProxyURL = in.ProxyURL
|
||||
out.DisableCompression = in.DisableCompression
|
||||
if err := Convert_Slice_v1_NamedExtension_To_Map_string_To_runtime_Object(&in.Extensions, &out.Extensions, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -277,7 +276,6 @@ func autoConvert_api_Cluster_To_v1_Cluster(in *api.Cluster, out *Cluster, s conv
|
||||
out.CertificateAuthority = in.CertificateAuthority
|
||||
out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData))
|
||||
out.ProxyURL = in.ProxyURL
|
||||
out.DisableCompression = in.DisableCompression
|
||||
if err := Convert_Map_string_To_runtime_Object_To_Slice_v1_NamedExtension(&in.Extensions, &out.Extensions, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"golang.org/x/term"
|
||||
@@ -58,7 +59,7 @@ func (a *PromptingAuthLoader) LoadAuth(path string) (*clientauth.Info, error) {
|
||||
if err != nil {
|
||||
return &auth, err
|
||||
}
|
||||
err = os.WriteFile(path, data, 0600)
|
||||
err = ioutil.WriteFile(path, data, 0600)
|
||||
return &auth, err
|
||||
}
|
||||
authPtr, err := clientauth.LoadFromFile(path)
|
||||
|
||||
@@ -19,6 +19,7 @@ package clientcmd
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -164,8 +165,6 @@ func (config *DirectClientConfig) ClientConfig() (*restclient.Config, error) {
|
||||
clientConfig.Proxy = http.ProxyURL(u)
|
||||
}
|
||||
|
||||
clientConfig.DisableCompression = configClusterInfo.DisableCompression
|
||||
|
||||
if config.overrides != nil && len(config.overrides.Timeout) > 0 {
|
||||
timeout, err := ParseTimeout(config.overrides.Timeout)
|
||||
if err != nil {
|
||||
@@ -247,7 +246,7 @@ func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthI
|
||||
mergedConfig.BearerToken = configAuthInfo.Token
|
||||
mergedConfig.BearerTokenFile = configAuthInfo.TokenFile
|
||||
} else if len(configAuthInfo.TokenFile) > 0 {
|
||||
tokenBytes, err := os.ReadFile(configAuthInfo.TokenFile)
|
||||
tokenBytes, err := ioutil.ReadFile(configAuthInfo.TokenFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -587,7 +586,7 @@ func (config *inClusterClientConfig) Namespace() (string, bool, error) {
|
||||
}
|
||||
|
||||
// Fall back to the namespace associated with the service account token, if available
|
||||
if data, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
|
||||
if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
|
||||
if ns := strings.TrimSpace(string(data)); len(ns) > 0 {
|
||||
return ns, false, nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package clientcmd
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -138,22 +139,6 @@ func createCAValidTestConfig() *clientcmdapi.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func TestDisableCompression(t *testing.T) {
|
||||
config := createValidTestConfig()
|
||||
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{
|
||||
ClusterInfo: clientcmdapi.Cluster{
|
||||
DisableCompression: true,
|
||||
},
|
||||
}, nil)
|
||||
|
||||
actualCfg, err := clientBuilder.ClientConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
matchBoolArg(true, actualCfg.DisableCompression, t)
|
||||
}
|
||||
|
||||
func TestInsecureOverridesCA(t *testing.T) {
|
||||
config := createCAValidTestConfig()
|
||||
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{
|
||||
@@ -173,7 +158,7 @@ func TestInsecureOverridesCA(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCAOverridesCAData(t *testing.T) {
|
||||
file, err := os.CreateTemp("", "my.ca")
|
||||
file, err := ioutil.TempFile("", "my.ca")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create tempfile: %v", err)
|
||||
}
|
||||
@@ -308,7 +293,7 @@ func TestModifyContext(t *testing.T) {
|
||||
"clean": true,
|
||||
}
|
||||
|
||||
tempPath, err := os.CreateTemp("", "testclientcmd-")
|
||||
tempPath, err := ioutil.TempFile("", "testclientcmd-")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -493,13 +478,13 @@ func TestBasicAuthData(t *testing.T) {
|
||||
|
||||
func TestBasicTokenFile(t *testing.T) {
|
||||
token := "exampletoken"
|
||||
f, err := os.CreateTemp("", "tokenfile")
|
||||
f, err := ioutil.TempFile("", "tokenfile")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
if err := os.WriteFile(f.Name(), []byte(token), 0644); err != nil {
|
||||
if err := ioutil.WriteFile(f.Name(), []byte(token), 0644); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -529,13 +514,13 @@ func TestBasicTokenFile(t *testing.T) {
|
||||
|
||||
func TestPrecedenceTokenFile(t *testing.T) {
|
||||
token := "exampletoken"
|
||||
f, err := os.CreateTemp("", "tokenfile")
|
||||
f, err := ioutil.TempFile("", "tokenfile")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
if err := os.WriteFile(f.Name(), []byte(token), 0644); err != nil {
|
||||
if err := ioutil.WriteFile(f.Name(), []byte(token), 0644); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -919,12 +904,12 @@ users:
|
||||
command: foo-command
|
||||
provideClusterInfo: true
|
||||
`
|
||||
tmpfile, err := os.CreateTemp("", "kubeconfig")
|
||||
tmpfile, err := ioutil.TempFile("", "kubeconfig")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
defer os.Remove(tmpfile.Name())
|
||||
if err := os.WriteFile(tmpfile.Name(), []byte(content), 0666); err != nil {
|
||||
if err := ioutil.WriteFile(tmpfile.Name(), []byte(content), 0666); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
config, err := BuildConfigFromFlags("", tmpfile.Name())
|
||||
|
||||
@@ -18,6 +18,7 @@ package clientcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -282,12 +283,12 @@ func (rules *ClientConfigLoadingRules) Migrate() error {
|
||||
return fmt.Errorf("cannot migrate %v to %v because it is a directory", source, destination)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(source)
|
||||
data, err := ioutil.ReadFile(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// destination is created with mode 0666 before umask
|
||||
err = os.WriteFile(destination, data, 0666)
|
||||
err = ioutil.WriteFile(destination, data, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -362,7 +363,7 @@ func (rules *ClientConfigLoadingRules) IsDefaultConfig(config *restclient.Config
|
||||
|
||||
// LoadFromFile takes a filename and deserializes the contents into Config object
|
||||
func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
|
||||
kubeconfigBytes, err := os.ReadFile(filename)
|
||||
kubeconfigBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -428,7 +429,7 @@ func WriteToFile(config clientcmdapi.Config, filename string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.WriteFile(filename, content, 0600); err != nil {
|
||||
if err := ioutil.WriteFile(filename, content, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -19,6 +19,7 @@ package clientcmd
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -73,8 +74,8 @@ var (
|
||||
"red-user": {Token: "a-different-red-token"},
|
||||
"yellow-user": {Token: "yellow-token"}},
|
||||
Clusters: map[string]*clientcmdapi.Cluster{
|
||||
"cow-cluster": {Server: "http://a-different-cow.org:8080", InsecureSkipTLSVerify: true, DisableCompression: true},
|
||||
"donkey-cluster": {Server: "http://donkey.org:8080", InsecureSkipTLSVerify: true, DisableCompression: true}},
|
||||
"cow-cluster": {Server: "http://a-different-cow.org:8080", InsecureSkipTLSVerify: true},
|
||||
"donkey-cluster": {Server: "http://donkey.org:8080", InsecureSkipTLSVerify: true}},
|
||||
CurrentContext: "federal-context",
|
||||
}
|
||||
)
|
||||
@@ -131,10 +132,10 @@ func TestToleratingMissingFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorReadingFile(t *testing.T) {
|
||||
commandLineFile, _ := os.CreateTemp("", "")
|
||||
commandLineFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(commandLineFile.Name())
|
||||
|
||||
if err := os.WriteFile(commandLineFile.Name(), []byte("bogus value"), 0644); err != nil {
|
||||
if err := ioutil.WriteFile(commandLineFile.Name(), []byte("bogus value"), 0644); err != nil {
|
||||
t.Fatalf("Error creating tempfile: %v", err)
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ func TestErrorReadingFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorReadingNonFile(t *testing.T) {
|
||||
tmpdir, err := os.MkdirTemp("", "")
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't create tmpdir")
|
||||
}
|
||||
@@ -172,9 +173,9 @@ func TestErrorReadingNonFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConflictingCurrentContext(t *testing.T) {
|
||||
commandLineFile, _ := os.CreateTemp("", "")
|
||||
commandLineFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(commandLineFile.Name())
|
||||
envVarFile, _ := os.CreateTemp("", "")
|
||||
envVarFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(envVarFile.Name())
|
||||
|
||||
mockCommandLineConfig := clientcmdapi.Config{
|
||||
@@ -253,7 +254,7 @@ users: null
|
||||
}
|
||||
|
||||
func TestLoadingEmptyMaps(t *testing.T) {
|
||||
configFile, _ := os.CreateTemp("", "")
|
||||
configFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(configFile.Name())
|
||||
|
||||
mockConfig := clientcmdapi.Config{
|
||||
@@ -279,10 +280,10 @@ func TestLoadingEmptyMaps(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDuplicateClusterName(t *testing.T) {
|
||||
configFile, _ := os.CreateTemp("", "")
|
||||
configFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(configFile.Name())
|
||||
|
||||
err := os.WriteFile(configFile.Name(), []byte(`
|
||||
err := ioutil.WriteFile(configFile.Name(), []byte(`
|
||||
kind: Config
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -321,10 +322,10 @@ users:
|
||||
}
|
||||
|
||||
func TestDuplicateContextName(t *testing.T) {
|
||||
configFile, _ := os.CreateTemp("", "")
|
||||
configFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(configFile.Name())
|
||||
|
||||
err := os.WriteFile(configFile.Name(), []byte(`
|
||||
err := ioutil.WriteFile(configFile.Name(), []byte(`
|
||||
kind: Config
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -363,10 +364,10 @@ users:
|
||||
}
|
||||
|
||||
func TestDuplicateUserName(t *testing.T) {
|
||||
configFile, _ := os.CreateTemp("", "")
|
||||
configFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(configFile.Name())
|
||||
|
||||
err := os.WriteFile(configFile.Name(), []byte(`
|
||||
err := ioutil.WriteFile(configFile.Name(), []byte(`
|
||||
kind: Config
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -403,10 +404,10 @@ users:
|
||||
}
|
||||
|
||||
func TestDuplicateExtensionName(t *testing.T) {
|
||||
configFile, _ := os.CreateTemp("", "")
|
||||
configFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(configFile.Name())
|
||||
|
||||
err := os.WriteFile(configFile.Name(), []byte(`
|
||||
err := ioutil.WriteFile(configFile.Name(), []byte(`
|
||||
kind: Config
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -471,14 +472,14 @@ func TestResolveRelativePaths(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
configDir1, _ := os.MkdirTemp("", "")
|
||||
configDir1, _ := ioutil.TempDir("", "")
|
||||
defer os.RemoveAll(configDir1)
|
||||
configFile1 := path.Join(configDir1, ".kubeconfig")
|
||||
configDir1, _ = filepath.Abs(configDir1)
|
||||
|
||||
configDir2, _ := os.MkdirTemp("", "")
|
||||
configDir2, _ := ioutil.TempDir("", "")
|
||||
defer os.RemoveAll(configDir2)
|
||||
configDir2, _ = os.MkdirTemp(configDir2, "")
|
||||
configDir2, _ = ioutil.TempDir(configDir2, "")
|
||||
configFile2 := path.Join(configDir2, ".kubeconfig")
|
||||
configDir2, _ = filepath.Abs(configDir2)
|
||||
|
||||
@@ -559,9 +560,9 @@ func TestResolveRelativePaths(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMigratingFile(t *testing.T) {
|
||||
sourceFile, _ := os.CreateTemp("", "")
|
||||
sourceFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(sourceFile.Name())
|
||||
destinationFile, _ := os.CreateTemp("", "")
|
||||
destinationFile, _ := ioutil.TempFile("", "")
|
||||
// delete the file so that we'll write to it
|
||||
os.Remove(destinationFile.Name())
|
||||
|
||||
@@ -578,11 +579,11 @@ func TestMigratingFile(t *testing.T) {
|
||||
// the load should have recreated this file
|
||||
defer os.Remove(destinationFile.Name())
|
||||
|
||||
sourceContent, err := os.ReadFile(sourceFile.Name())
|
||||
sourceContent, err := ioutil.ReadFile(sourceFile.Name())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
destinationContent, err := os.ReadFile(destinationFile.Name())
|
||||
destinationContent, err := ioutil.ReadFile(destinationFile.Name())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
@@ -593,9 +594,9 @@ func TestMigratingFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMigratingFileLeaveExistingFileAlone(t *testing.T) {
|
||||
sourceFile, _ := os.CreateTemp("", "")
|
||||
sourceFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(sourceFile.Name())
|
||||
destinationFile, _ := os.CreateTemp("", "")
|
||||
destinationFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(destinationFile.Name())
|
||||
|
||||
WriteToFile(testConfigAlfa, sourceFile.Name())
|
||||
@@ -608,7 +609,7 @@ func TestMigratingFileLeaveExistingFileAlone(t *testing.T) {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
destinationContent, err := os.ReadFile(destinationFile.Name())
|
||||
destinationContent, err := ioutil.ReadFile(destinationFile.Name())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
@@ -620,7 +621,7 @@ func TestMigratingFileLeaveExistingFileAlone(t *testing.T) {
|
||||
|
||||
func TestMigratingFileSourceMissingSkip(t *testing.T) {
|
||||
sourceFilename := "some-missing-file"
|
||||
destinationFile, _ := os.CreateTemp("", "")
|
||||
destinationFile, _ := ioutil.TempFile("", "")
|
||||
// delete the file so that we'll write to it
|
||||
os.Remove(destinationFile.Name())
|
||||
|
||||
@@ -638,7 +639,7 @@ func TestMigratingFileSourceMissingSkip(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFileLocking(t *testing.T) {
|
||||
f, _ := os.CreateTemp("", "")
|
||||
f, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
err := lockFile(f.Name())
|
||||
@@ -654,9 +655,9 @@ func TestFileLocking(t *testing.T) {
|
||||
}
|
||||
|
||||
func Example_noMergingOnExplicitPaths() {
|
||||
commandLineFile, _ := os.CreateTemp("", "")
|
||||
commandLineFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(commandLineFile.Name())
|
||||
envVarFile, _ := os.CreateTemp("", "")
|
||||
envVarFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(envVarFile.Name())
|
||||
|
||||
WriteToFile(testConfigAlfa, commandLineFile.Name())
|
||||
@@ -703,9 +704,9 @@ func Example_noMergingOnExplicitPaths() {
|
||||
}
|
||||
|
||||
func Example_mergingSomeWithConflict() {
|
||||
commandLineFile, _ := os.CreateTemp("", "")
|
||||
commandLineFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(commandLineFile.Name())
|
||||
envVarFile, _ := os.CreateTemp("", "")
|
||||
envVarFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(envVarFile.Name())
|
||||
|
||||
WriteToFile(testConfigAlfa, commandLineFile.Name())
|
||||
@@ -736,7 +737,6 @@ func Example_mergingSomeWithConflict() {
|
||||
// server: http://cow.org:8080
|
||||
// name: cow-cluster
|
||||
// - cluster:
|
||||
// disable-compression: true
|
||||
// insecure-skip-tls-verify: true
|
||||
// server: http://donkey.org:8080
|
||||
// name: donkey-cluster
|
||||
@@ -759,13 +759,13 @@ func Example_mergingSomeWithConflict() {
|
||||
}
|
||||
|
||||
func Example_mergingEverythingNoConflicts() {
|
||||
commandLineFile, _ := os.CreateTemp("", "")
|
||||
commandLineFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(commandLineFile.Name())
|
||||
envVarFile, _ := os.CreateTemp("", "")
|
||||
envVarFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(envVarFile.Name())
|
||||
currentDirFile, _ := os.CreateTemp("", "")
|
||||
currentDirFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(currentDirFile.Name())
|
||||
homeDirFile, _ := os.CreateTemp("", "")
|
||||
homeDirFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(homeDirFile.Name())
|
||||
|
||||
WriteToFile(testConfigAlfa, commandLineFile.Name())
|
||||
|
||||
@@ -17,13 +17,14 @@ limitations under the License.
|
||||
package clientcmd
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
tmp, err := os.MkdirTemp("", "testkubeconfig")
|
||||
tmp, err := ioutil.TempDir("", "testkubeconfig")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ type ClusterOverrideFlags struct {
|
||||
InsecureSkipTLSVerify FlagInfo
|
||||
TLSServerName FlagInfo
|
||||
ProxyURL FlagInfo
|
||||
DisableCompression FlagInfo
|
||||
}
|
||||
|
||||
// FlagInfo contains information about how to register a flag. This struct is useful if you want to provide a way for an extender to
|
||||
@@ -144,26 +143,25 @@ func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
|
||||
}
|
||||
|
||||
const (
|
||||
FlagClusterName = "cluster"
|
||||
FlagAuthInfoName = "user"
|
||||
FlagContext = "context"
|
||||
FlagNamespace = "namespace"
|
||||
FlagAPIServer = "server"
|
||||
FlagTLSServerName = "tls-server-name"
|
||||
FlagInsecure = "insecure-skip-tls-verify"
|
||||
FlagCertFile = "client-certificate"
|
||||
FlagKeyFile = "client-key"
|
||||
FlagCAFile = "certificate-authority"
|
||||
FlagEmbedCerts = "embed-certs"
|
||||
FlagBearerToken = "token"
|
||||
FlagImpersonate = "as"
|
||||
FlagImpersonateUID = "as-uid"
|
||||
FlagImpersonateGroup = "as-group"
|
||||
FlagUsername = "username"
|
||||
FlagPassword = "password"
|
||||
FlagTimeout = "request-timeout"
|
||||
FlagProxyURL = "proxy-url"
|
||||
FlagDisableCompression = "disable-compression"
|
||||
FlagClusterName = "cluster"
|
||||
FlagAuthInfoName = "user"
|
||||
FlagContext = "context"
|
||||
FlagNamespace = "namespace"
|
||||
FlagAPIServer = "server"
|
||||
FlagTLSServerName = "tls-server-name"
|
||||
FlagInsecure = "insecure-skip-tls-verify"
|
||||
FlagCertFile = "client-certificate"
|
||||
FlagKeyFile = "client-key"
|
||||
FlagCAFile = "certificate-authority"
|
||||
FlagEmbedCerts = "embed-certs"
|
||||
FlagBearerToken = "token"
|
||||
FlagImpersonate = "as"
|
||||
FlagImpersonateUID = "as-uid"
|
||||
FlagImpersonateGroup = "as-group"
|
||||
FlagUsername = "username"
|
||||
FlagPassword = "password"
|
||||
FlagTimeout = "request-timeout"
|
||||
FlagProxyURL = "proxy-url"
|
||||
)
|
||||
|
||||
// RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
|
||||
@@ -200,7 +198,6 @@ func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags {
|
||||
InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"},
|
||||
TLSServerName: FlagInfo{prefix + FlagTLSServerName, "", "", "If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used."},
|
||||
ProxyURL: FlagInfo{prefix + FlagProxyURL, "", "", "If provided, this URL will be used to connect via proxy"},
|
||||
DisableCompression: FlagInfo{prefix + FlagDisableCompression, "", "", "If true, opt-out of response compression for all requests to the server"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +238,6 @@ func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, f
|
||||
flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify)
|
||||
flagNames.TLSServerName.BindStringFlag(flags, &clusterInfo.TLSServerName)
|
||||
flagNames.ProxyURL.BindStringFlag(flags, &clusterInfo.ProxyURL)
|
||||
flagNames.DisableCompression.BindBoolFlag(flags, &clusterInfo.DisableCompression)
|
||||
}
|
||||
|
||||
// BindFlags is a convenience method to bind the specified flags to their associated variables
|
||||
|
||||
@@ -19,6 +19,7 @@ package clientcmd
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -295,7 +296,7 @@ func TestValidateCleanClusterInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateCleanWithCAClusterInfo(t *testing.T) {
|
||||
tempFile, _ := os.CreateTemp("", "")
|
||||
tempFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
config := clientcmdapi.NewConfig()
|
||||
@@ -338,7 +339,7 @@ func TestValidateCertFilesNotFoundAuthInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateCertDataOverridesFiles(t *testing.T) {
|
||||
tempFile, _ := os.CreateTemp("", "")
|
||||
tempFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
config := clientcmdapi.NewConfig()
|
||||
@@ -358,7 +359,7 @@ func TestValidateCertDataOverridesFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateCleanCertFilesAuthInfo(t *testing.T) {
|
||||
tempFile, _ := os.CreateTemp("", "")
|
||||
tempFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
config := clientcmdapi.NewConfig()
|
||||
|
||||
@@ -1019,21 +1019,58 @@ func testReleaseOnCancellation(t *testing.T, objectType string) {
|
||||
onRelease = make(chan struct{})
|
||||
|
||||
lockObj runtime.Object
|
||||
gets int
|
||||
updates int
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
resetVars := func() {
|
||||
onNewLeader = make(chan struct{})
|
||||
onRenewCalled = make(chan struct{})
|
||||
onRenewResume = make(chan struct{})
|
||||
onRelease = make(chan struct{})
|
||||
|
||||
lockObj = nil
|
||||
gets = 0
|
||||
updates = 0
|
||||
resourceLockConfig := rl.ResourceLockConfig{
|
||||
Identity: "baz",
|
||||
EventRecorder: &record.FakeRecorder{},
|
||||
}
|
||||
c := &fake.Clientset{}
|
||||
|
||||
c.AddReactor("get", objectType, func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if lockObj != nil {
|
||||
return true, lockObj, nil
|
||||
}
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
})
|
||||
|
||||
// create lock
|
||||
c.AddReactor("create", objectType, func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
lockObj = action.(fakeclient.CreateAction).GetObject()
|
||||
return true, lockObj, nil
|
||||
})
|
||||
|
||||
c.AddReactor("update", objectType, func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
updates++
|
||||
|
||||
// Second update (first renew) should return our canceled error
|
||||
// FakeClient doesn't do anything with the context so we're doing this ourselves
|
||||
if updates == 2 {
|
||||
close(onRenewCalled)
|
||||
<-onRenewResume
|
||||
return true, nil, context.Canceled
|
||||
} else if updates == 3 {
|
||||
close(onRelease)
|
||||
}
|
||||
|
||||
lockObj = action.(fakeclient.UpdateAction).GetObject()
|
||||
return true, lockObj, nil
|
||||
|
||||
})
|
||||
|
||||
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.Fatal("resourcelock.New() = ", err)
|
||||
}
|
||||
|
||||
lec := LeaderElectionConfig{
|
||||
Lock: lock,
|
||||
LeaseDuration: 15 * time.Second,
|
||||
RenewDeadline: 2 * time.Second,
|
||||
RetryPeriod: 1 * time.Second,
|
||||
@@ -1050,168 +1087,40 @@ func testReleaseOnCancellation(t *testing.T, objectType string) {
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
reactors []Reactor
|
||||
}{
|
||||
{
|
||||
name: "release acquired lock on cancellation of update",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: objectType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
gets++
|
||||
if lockObj != nil {
|
||||
return true, lockObj, nil
|
||||
}
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "create",
|
||||
objectType: objectType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
lockObj = action.(fakeclient.CreateAction).GetObject()
|
||||
return true, lockObj, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: objectType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
updates++
|
||||
|
||||
// Second update (first renew) should return our canceled error
|
||||
// FakeClient doesn't do anything with the context so we're doing this ourselves
|
||||
if updates == 2 {
|
||||
close(onRenewCalled)
|
||||
<-onRenewResume
|
||||
return true, nil, context.Canceled
|
||||
} else if updates == 3 {
|
||||
// We update the lock after the cancellation to release it
|
||||
// This wg is to avoid the data race on lockObj
|
||||
defer wg.Done()
|
||||
close(onRelease)
|
||||
}
|
||||
|
||||
lockObj = action.(fakeclient.UpdateAction).GetObject()
|
||||
return true, lockObj, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "release acquired lock on cancellation of get",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: objectType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
gets++
|
||||
if lockObj != nil {
|
||||
// Third and more get (first create, second renew) should return our canceled error
|
||||
// FakeClient doesn't do anything with the context so we're doing this ourselves
|
||||
if gets >= 3 {
|
||||
close(onRenewCalled)
|
||||
<-onRenewResume
|
||||
return true, nil, context.Canceled
|
||||
}
|
||||
return true, lockObj, nil
|
||||
}
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "create",
|
||||
objectType: objectType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
lockObj = action.(fakeclient.CreateAction).GetObject()
|
||||
return true, lockObj, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: objectType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
updates++
|
||||
// Second update (first renew) should release the lock
|
||||
if updates == 2 {
|
||||
// We update the lock after the cancellation to release it
|
||||
// This wg is to avoid the data race on lockObj
|
||||
defer wg.Done()
|
||||
close(onRelease)
|
||||
}
|
||||
|
||||
lockObj = action.(fakeclient.UpdateAction).GetObject()
|
||||
return true, lockObj, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
elector, err := NewLeaderElector(lec)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create leader elector: ", err)
|
||||
}
|
||||
|
||||
for i := range tests {
|
||||
test := &tests[i]
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
wg.Add(1)
|
||||
resetVars()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
resourceLockConfig := rl.ResourceLockConfig{
|
||||
Identity: "baz",
|
||||
EventRecorder: &record.FakeRecorder{},
|
||||
}
|
||||
c := &fake.Clientset{}
|
||||
for _, reactor := range test.reactors {
|
||||
c.AddReactor(reactor.verb, 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.Fatal("resourcelock.New() = ", err)
|
||||
}
|
||||
go elector.Run(ctx)
|
||||
|
||||
lec.Lock = lock
|
||||
elector, err := NewLeaderElector(lec)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create leader elector: ", err)
|
||||
}
|
||||
// Wait for us to become the leader
|
||||
select {
|
||||
case <-onNewLeader:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("failed to become the leader")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
// Wait for renew (update) to be invoked
|
||||
select {
|
||||
case <-onRenewCalled:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("the elector failed to renew the lock")
|
||||
}
|
||||
|
||||
go elector.Run(ctx)
|
||||
// Cancel the context - stopping the elector while
|
||||
// it's running
|
||||
cancel()
|
||||
|
||||
// Wait for us to become the leader
|
||||
select {
|
||||
case <-onNewLeader:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("failed to become the leader")
|
||||
}
|
||||
// Resume the update call to return the cancellation
|
||||
// which should trigger the release flow
|
||||
close(onRenewResume)
|
||||
|
||||
// Wait for renew (update) to be invoked
|
||||
select {
|
||||
case <-onRenewCalled:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("the elector failed to renew the lock")
|
||||
}
|
||||
|
||||
// Cancel the context - stopping the elector while
|
||||
// it's running
|
||||
cancel()
|
||||
|
||||
// Resume the tryAcquireOrRenew call to return the cancellation
|
||||
// which should trigger the release flow
|
||||
close(onRenewResume)
|
||||
|
||||
select {
|
||||
case <-onRelease:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("the lock was not released")
|
||||
}
|
||||
wg.Wait()
|
||||
})
|
||||
select {
|
||||
case <-onRelease:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("the lock was not released")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,11 +44,11 @@ type configMapLock struct {
|
||||
// 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{})
|
||||
var err error
|
||||
cml.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)
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ type endpointsLock struct {
|
||||
// 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{})
|
||||
var err error
|
||||
el.e, 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)
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ type LeaseLock struct {
|
||||
|
||||
// Get returns the election record from a Lease spec
|
||||
func (ll *LeaseLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) {
|
||||
lease, err := ll.Client.Leases(ll.LeaseMeta.Namespace).Get(ctx, ll.LeaseMeta.Name, metav1.GetOptions{})
|
||||
var err error
|
||||
ll.lease, err = ll.Client.Leases(ll.LeaseMeta.Namespace).Get(ctx, ll.LeaseMeta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ll.lease = lease
|
||||
record := LeaseSpecToLeaderElectionRecord(&ll.lease.Spec)
|
||||
recordByte, err := json.Marshal(*record)
|
||||
if err != nil {
|
||||
|
||||
@@ -203,11 +203,6 @@ func (p *ListPager) eachListChunkBuffered(ctx context.Context, options metav1.Li
|
||||
}()
|
||||
|
||||
for o := range chunkC {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
err := fn(o)
|
||||
if err != nil {
|
||||
return err // any fn error should be returned immediately
|
||||
|
||||
@@ -301,10 +301,16 @@ func TestListPager_EachListItem(t *testing.T) {
|
||||
{
|
||||
name: "cancel context while processing",
|
||||
fields: fields{PageSize: 10, PageFn: (&testPager{t: t, expectPage: 10, remaining: 51, rv: "rv:20"}).PagedList},
|
||||
want: list(10, "rv:20"), // The whole PageSize worth of items got returned.
|
||||
want: list(3, "rv:20"), // all the items <= the one the processor returned an error on should have been visited
|
||||
wantErr: true,
|
||||
cancelContextOnItem: 3,
|
||||
},
|
||||
{
|
||||
name: "panic processing item",
|
||||
fields: fields{PageSize: 10, PageFn: (&testPager{t: t, expectPage: 10, remaining: 51, rv: "rv:20"}).PagedList},
|
||||
want: list(3, "rv:20"), // all the items <= the one the processor returned an error on should have been visited
|
||||
wantPanic: true,
|
||||
},
|
||||
}
|
||||
|
||||
processorErr := fmt.Errorf("processor error")
|
||||
@@ -339,7 +345,8 @@ func TestListPager_EachListItem(t *testing.T) {
|
||||
err = p.EachListItem(ctx, metav1.ListOptions{}, fn)
|
||||
}()
|
||||
if (panic != nil) && !tt.wantPanic {
|
||||
t.Errorf(".EachListItem() panic = %v, wantPanic %v", panic, tt.wantPanic)
|
||||
t.Fatalf(".EachListItem() panic = %v, wantPanic %v", panic, tt.wantPanic)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
if (err != nil) != tt.wantErr {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"sort"
|
||||
@@ -347,11 +348,10 @@ func (pf *PortForwarder) handleConnection(conn net.Conn, port ForwardedPort) {
|
||||
}
|
||||
// we're not writing to this stream
|
||||
errorStream.Close()
|
||||
defer pf.streamConn.RemoveStreams(errorStream)
|
||||
|
||||
errorChan := make(chan error)
|
||||
go func() {
|
||||
message, err := io.ReadAll(errorStream)
|
||||
message, err := ioutil.ReadAll(errorStream)
|
||||
switch {
|
||||
case err != nil:
|
||||
errorChan <- fmt.Errorf("error reading from error stream for port %d -> %d: %v", port.Local, port.Remote, err)
|
||||
@@ -368,7 +368,6 @@ func (pf *PortForwarder) handleConnection(conn net.Conn, port ForwardedPort) {
|
||||
runtime.HandleError(fmt.Errorf("error creating forwarding stream for port %d -> %d: %v", port.Local, port.Remote, err))
|
||||
return
|
||||
}
|
||||
defer pf.streamConn.RemoveStreams(dataStream)
|
||||
|
||||
localError := make(chan struct{})
|
||||
remoteDone := make(chan struct{})
|
||||
|
||||
@@ -51,7 +51,6 @@ type fakeConnection struct {
|
||||
closeChan chan bool
|
||||
dataStream *fakeStream
|
||||
errorStream *fakeStream
|
||||
streamCount int
|
||||
}
|
||||
|
||||
func newFakeConnection() *fakeConnection {
|
||||
@@ -65,10 +64,8 @@ func newFakeConnection() *fakeConnection {
|
||||
func (c *fakeConnection) CreateStream(headers http.Header) (httpstream.Stream, error) {
|
||||
switch headers.Get(v1.StreamType) {
|
||||
case v1.StreamTypeData:
|
||||
c.streamCount++
|
||||
return c.dataStream, nil
|
||||
case v1.StreamTypeError:
|
||||
c.streamCount++
|
||||
return c.errorStream, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("fakeStream creation not supported for stream type %s", headers.Get(v1.StreamType))
|
||||
@@ -87,10 +84,7 @@ func (c *fakeConnection) CloseChan() <-chan bool {
|
||||
return c.closeChan
|
||||
}
|
||||
|
||||
func (c *fakeConnection) RemoveStreams(streams ...httpstream.Stream) {
|
||||
for range streams {
|
||||
c.streamCount--
|
||||
}
|
||||
func (c *fakeConnection) RemoveStreams(_ ...httpstream.Stream) {
|
||||
}
|
||||
|
||||
func (c *fakeConnection) SetIdleTimeout(timeout time.Duration) {
|
||||
@@ -510,7 +504,7 @@ func TestHandleConnection(t *testing.T) {
|
||||
|
||||
// Test handleConnection
|
||||
pf.handleConnection(localConnection, ForwardedPort{Local: 1111, Remote: 2222})
|
||||
assert.Equal(t, 0, remoteConnection.streamCount, "stream count should be zero")
|
||||
|
||||
assert.Equal(t, "test data from local", remoteDataReceived.String())
|
||||
assert.Equal(t, "test data from remote", localConnection.receiveBuffer.String())
|
||||
assert.Equal(t, "Handling connection for 1111\n", out.String())
|
||||
@@ -544,7 +538,6 @@ func TestHandleConnectionSendsRemoteError(t *testing.T) {
|
||||
// Test handleConnection, using go-routine because it needs to be able to write to unbuffered pf.errorChan
|
||||
pf.handleConnection(localConnection, ForwardedPort{Local: 1111, Remote: 2222})
|
||||
|
||||
assert.Equal(t, 0, remoteConnection.streamCount, "stream count should be zero")
|
||||
assert.Equal(t, "", remoteDataReceived.String())
|
||||
assert.Equal(t, "", localConnection.receiveBuffer.String())
|
||||
assert.Equal(t, "Handling connection for 1111\n", out.String())
|
||||
|
||||
@@ -19,6 +19,7 @@ package remotecommand
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
@@ -38,7 +39,7 @@ func watchErrorStream(errorStream io.Reader, d errorStreamDecoder) chan error {
|
||||
go func() {
|
||||
defer runtime.HandleCrash()
|
||||
|
||||
message, err := io.ReadAll(errorStream)
|
||||
message, err := ioutil.ReadAll(errorStream)
|
||||
switch {
|
||||
case err != nil && err != io.EOF:
|
||||
errorChan <- fmt.Errorf("error reading from error stream: %s", err)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user