Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove old, core/v1 specific constructs from RESTClient #48991

Merged
merged 3 commits into from
Jul 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 15 additions & 7 deletions pkg/kubectl/resource/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (m *Helper) Get(namespace, name string, export bool) (runtime.Object, error
Resource(m.Resource).
Name(name)
if export {
// TODO: I should be part of GetOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/I/It/

req.Param("export", strconv.FormatBool(export))
}
return req.Do().Get()
Expand All @@ -68,8 +69,11 @@ func (m *Helper) List(namespace, apiVersion string, selector labels.Selector, ex
req := m.RESTClient.Get().
NamespaceIfScoped(namespace, m.NamespaceScoped).
Resource(m.Resource).
LabelsSelectorParam(selector)
VersionedParams(&metav1.ListOptions{
LabelSelector: selector.String(),
}, metav1.ParameterCodec)
if export {
// TODO: I should be part of ListOptions
req.Param("export", strconv.FormatBool(export))
}
return req.Do().Get()
Expand All @@ -79,19 +83,23 @@ func (m *Helper) Watch(namespace, resourceVersion, apiVersion string, labelSelec
return m.RESTClient.Get().
NamespaceIfScoped(namespace, m.NamespaceScoped).
Resource(m.Resource).
Param("resourceVersion", resourceVersion).
Param("watch", "true").
LabelsSelectorParam(labelSelector).
VersionedParams(&metav1.ListOptions{
ResourceVersion: resourceVersion,
Watch: true,
LabelSelector: labelSelector.String(),
}, metav1.ParameterCodec).
Watch()
}

func (m *Helper) WatchSingle(namespace, name, resourceVersion string) (watch.Interface, error) {
return m.RESTClient.Get().
NamespaceIfScoped(namespace, m.NamespaceScoped).
Resource(m.Resource).
Param("resourceVersion", resourceVersion).
Param("watch", "true").
FieldsSelectorParam(fields.OneTermEqualSelector("metadata.name", name)).
VersionedParams(&metav1.ListOptions{
ResourceVersion: resourceVersion,
Watch: true,
FieldSelector: fields.OneTermEqualSelector("metadata.name", name).String(),
}, metav1.ParameterCodec).
Watch()
}

Expand Down
3 changes: 0 additions & 3 deletions staging/src/k8s.io/client-go/rest/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
Expand Down Expand Up @@ -65,8 +64,6 @@ go_library(
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
Expand Down
192 changes: 6 additions & 186 deletions staging/src/k8s.io/client-go/rest/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,19 @@ import (
"time"

"github.com/golang/glog"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
restclientwatch "k8s.io/client-go/rest/watch"
"k8s.io/client-go/tools/metrics"
"k8s.io/client-go/util/flowcontrol"
)

var (
// specialParams lists parameters that are handled specially and which users of Request
// are therefore not allowed to set manually.
specialParams = sets.NewString("timeout")

// longThrottleLatency defines threshold for logging requests. All requests being
// throttle for more than longThrottleLatency will be logged.
longThrottleLatency = 50 * time.Millisecond
Expand Down Expand Up @@ -269,7 +261,7 @@ func (r *Request) AbsPath(segments ...string) *Request {
}

// RequestURI overwrites existing path and parameters with the value of the provided server relative
// URI. Some parameters (those in specialParameters) cannot be overwritten.
// URI.
func (r *Request) RequestURI(uri string) *Request {
if r.err != nil {
return r
Expand All @@ -291,143 +283,6 @@ func (r *Request) RequestURI(uri string) *Request {
return r
}

const (
// A constant that clients can use to refer in a field selector to the object name field.
// Will be automatically emitted as the correct name for the API version.
nodeUnschedulable = "spec.unschedulable"
objectNameField = "metadata.name"
podHost = "spec.nodeName"
podStatus = "status.phase"
secretType = "type"

eventReason = "reason"
eventSource = "source"
eventType = "type"
eventInvolvedKind = "involvedObject.kind"
eventInvolvedNamespace = "involvedObject.namespace"
eventInvolvedName = "involvedObject.name"
eventInvolvedUID = "involvedObject.uid"
eventInvolvedAPIVersion = "involvedObject.apiVersion"
eventInvolvedResourceVersion = "involvedObject.resourceVersion"
eventInvolvedFieldPath = "involvedObject.fieldPath"
)

type clientFieldNameToAPIVersionFieldName map[string]string

func (c clientFieldNameToAPIVersionFieldName) filterField(field, value string) (newField, newValue string, err error) {
newFieldName, ok := c[field]
if !ok {
return "", "", fmt.Errorf("%v - %v - no field mapping defined", field, value)
}
return newFieldName, value, nil
}

type resourceTypeToFieldMapping map[string]clientFieldNameToAPIVersionFieldName

func (r resourceTypeToFieldMapping) filterField(resourceType, field, value string) (newField, newValue string, err error) {
fMapping, ok := r[resourceType]
if !ok {
return "", "", fmt.Errorf("%v - %v - %v - no field mapping defined", resourceType, field, value)
}
return fMapping.filterField(field, value)
}

type versionToResourceToFieldMapping map[schema.GroupVersion]resourceTypeToFieldMapping

// filterField transforms the given field/value selector for the given groupVersion and resource
func (v versionToResourceToFieldMapping) filterField(groupVersion *schema.GroupVersion, resourceType, field, value string) (newField, newValue string, err error) {
rMapping, ok := v[*groupVersion]
if !ok {
// no groupVersion overrides registered, default to identity mapping
return field, value, nil
}
newField, newValue, err = rMapping.filterField(resourceType, field, value)
if err != nil {
// no groupVersionResource overrides registered, default to identity mapping
return field, value, nil
}
return newField, newValue, nil
}

var fieldMappings = versionToResourceToFieldMapping{
v1.SchemeGroupVersion: resourceTypeToFieldMapping{
"nodes": clientFieldNameToAPIVersionFieldName{
objectNameField: objectNameField,
nodeUnschedulable: nodeUnschedulable,
},
"pods": clientFieldNameToAPIVersionFieldName{
objectNameField: objectNameField,
podHost: podHost,
podStatus: podStatus,
},
"secrets": clientFieldNameToAPIVersionFieldName{
secretType: secretType,
},
"serviceAccounts": clientFieldNameToAPIVersionFieldName{
objectNameField: objectNameField,
},
"endpoints": clientFieldNameToAPIVersionFieldName{
objectNameField: objectNameField,
},
"events": clientFieldNameToAPIVersionFieldName{
objectNameField: objectNameField,
eventReason: eventReason,
eventSource: eventSource,
eventType: eventType,
eventInvolvedKind: eventInvolvedKind,
eventInvolvedNamespace: eventInvolvedNamespace,
eventInvolvedName: eventInvolvedName,
eventInvolvedUID: eventInvolvedUID,
eventInvolvedAPIVersion: eventInvolvedAPIVersion,
eventInvolvedResourceVersion: eventInvolvedResourceVersion,
eventInvolvedFieldPath: eventInvolvedFieldPath,
},
},
}

// FieldsSelectorParam adds the given selector as a query parameter with the name paramName.
func (r *Request) FieldsSelectorParam(s fields.Selector) *Request {
if r.err != nil {
return r
}
if s == nil {
return r
}
if s.Empty() {
return r
}
s2, err := s.Transform(func(field, value string) (newField, newValue string, err error) {
return fieldMappings.filterField(r.content.GroupVersion, r.resource, field, value)
})
if err != nil {
r.err = err
return r
}
return r.setParam(metav1.FieldSelectorQueryParam(r.content.GroupVersion.String()), s2.String())
}

// LabelsSelectorParam adds the given selector as a query parameter
func (r *Request) LabelsSelectorParam(s labels.Selector) *Request {
if r.err != nil {
return r
}
if s == nil {
return r
}
if s.Empty() {
return r
}
return r.setParam(metav1.LabelSelectorQueryParam(r.content.GroupVersion.String()), s.String())
}

// UintParam creates a query parameter with the given value.
func (r *Request) UintParam(paramName string, u uint64) *Request {
if r.err != nil {
return r
}
return r.setParam(paramName, strconv.FormatUint(u, 10))
}

// Param creates a query parameter with the given string value.
func (r *Request) Param(paramName, s string) *Request {
if r.err != nil {
Expand All @@ -439,6 +294,8 @@ func (r *Request) Param(paramName, s string) *Request {
// VersionedParams will take the provided object, serialize it to a map[string][]string using the
// implicit RESTClient API version and the default parameter codec, and then add those as parameters
// to the request. Use this to provide versioned query parameters from client libraries.
// VersionedParams will not write query parameters that have omitempty set and are empty. If a
// parameter has already been set it is appended to (Params and VersionedParams are additive).
func (r *Request) VersionedParams(obj runtime.Object, codec runtime.ParameterCodec) *Request {
if r.err != nil {
return r
Expand All @@ -449,52 +306,15 @@ func (r *Request) VersionedParams(obj runtime.Object, codec runtime.ParameterCod
return r
}
for k, v := range params {
for _, value := range v {
// TODO: Move it to setParam method, once we get rid of
// FieldSelectorParam & LabelSelectorParam methods.
if k == metav1.LabelSelectorQueryParam(r.content.GroupVersion.String()) && value == "" {
// Don't set an empty selector for backward compatibility.
// Since there is no way to get the difference between empty
// and unspecified string, we don't set it to avoid having
// labelSelector= param in every request.
continue
}
if k == metav1.FieldSelectorQueryParam(r.content.GroupVersion.String()) {
if len(value) == 0 {
// Don't set an empty selector for backward compatibility.
// Since there is no way to get the difference between empty
// and unspecified string, we don't set it to avoid having
// fieldSelector= param in every request.
continue
}
// TODO: Filtering should be handled somewhere else.
selector, err := fields.ParseSelector(value)
if err != nil {
r.err = fmt.Errorf("unparsable field selector: %v", err)
return r
}
filteredSelector, err := selector.Transform(
func(field, value string) (newField, newValue string, err error) {
return fieldMappings.filterField(r.content.GroupVersion, r.resource, field, value)
})
if err != nil {
r.err = fmt.Errorf("untransformable field selector: %v", err)
return r
}
value = filteredSelector.String()
}

r.setParam(k, value)
if r.params == nil {
r.params = make(url.Values)
}
r.params[k] = append(r.params[k], v...)
}
return r
}

func (r *Request) setParam(paramName, value string) *Request {
if specialParams.Has(paramName) {
r.err = fmt.Errorf("must set %v through the corresponding function, not directly.", paramName)
return r
}
if r.params == nil {
r.params = make(url.Values)
}
Expand Down