Compare commits

..

1 Commits

Author SHA1 Message Date
Kubernetes Publisher
0e86f563ac Update dependencies to v0.25.0-beta.0 tag 2022-08-05 00:25:27 +00:00
120 changed files with 577 additions and 4806 deletions

1
OWNERS
View File

@@ -9,7 +9,6 @@ approvers:
- sttts
- yliaog
reviewers:
- aojea
- caesarxuchao
- deads2k
- jpbetz

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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:

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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)
}
}

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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() {

View File

@@ -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)
}

View File

@@ -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() {

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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())
}

View File

@@ -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}
}

View File

@@ -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)

View File

@@ -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}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{}

View File

@@ -1,64 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package 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
}

View File

@@ -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
}),

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{}

View File

@@ -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
}

View File

@@ -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{

View File

@@ -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
}

View File

@@ -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{}

View File

@@ -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)
}

View File

@@ -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.
//

View File

@@ -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.
//

View File

@@ -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
}

View File

@@ -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.
//

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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")
}
}

View File

@@ -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)

View File

@@ -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
}

View 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`)
}

View File

@@ -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"
)

View File

@@ -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
}

View File

@@ -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)
}
})
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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")
}

View File

@@ -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()
}

View File

@@ -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 {

View File

@@ -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})
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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"`

View File

@@ -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:

View File

@@ -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"`

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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())

View File

@@ -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

View File

@@ -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())

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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")
}
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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{})

View File

@@ -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())

View File

@@ -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