mirror of
https://github.com/kubernetes/client-go.git
synced 2025-09-26 07:10:41 +00:00
published by bot
(https://github.com/kubernetes/contrib/tree/master/mungegithub) copied from https://github.com/kubernetes/kubernetes.git, branch master, last commit is 8d5227bb2e05e01031ace81fa6611a13f598278e
This commit is contained in:
@@ -28,7 +28,7 @@ import (
|
||||
"k8s.io/client-go/pkg/api"
|
||||
"k8s.io/client-go/pkg/api/testapi"
|
||||
"k8s.io/client-go/pkg/util/flowcontrol"
|
||||
"k8s.io/client-go/rest"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
func CreateHTTPClient(roundTripper func(*http.Request) (*http.Response, error)) *http.Client {
|
||||
@@ -54,27 +54,27 @@ type RESTClient struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (c *RESTClient) Get() *rest.Request {
|
||||
func (c *RESTClient) Get() *restclient.Request {
|
||||
return c.request("GET")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Put() *rest.Request {
|
||||
func (c *RESTClient) Put() *restclient.Request {
|
||||
return c.request("PUT")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Patch(_ types.PatchType) *rest.Request {
|
||||
func (c *RESTClient) Patch(_ types.PatchType) *restclient.Request {
|
||||
return c.request("PATCH")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Post() *rest.Request {
|
||||
func (c *RESTClient) Post() *restclient.Request {
|
||||
return c.request("POST")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Delete() *rest.Request {
|
||||
func (c *RESTClient) Delete() *restclient.Request {
|
||||
return c.request("DELETE")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Verb(verb string) *rest.Request {
|
||||
func (c *RESTClient) Verb(verb string) *restclient.Request {
|
||||
return c.request(verb)
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ func (c *RESTClient) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RESTClient) request(verb string) *rest.Request {
|
||||
config := rest.ContentConfig{
|
||||
func (c *RESTClient) request(verb string) *restclient.Request {
|
||||
config := restclient.ContentConfig{
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
GroupVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion,
|
||||
NegotiatedSerializer: c.NegotiatedSerializer,
|
||||
@@ -104,7 +104,7 @@ func (c *RESTClient) request(verb string) *rest.Request {
|
||||
Version: runtime.APIVersionInternal,
|
||||
}
|
||||
internalVersion.Version = runtime.APIVersionInternal
|
||||
serializers := rest.Serializers{
|
||||
serializers := restclient.Serializers{
|
||||
Encoder: ns.EncoderForVersion(info.Serializer, api.Registry.GroupOrDie(api.GroupName).GroupVersion),
|
||||
Decoder: ns.DecoderToVersion(info.Serializer, internalVersion),
|
||||
}
|
||||
@@ -112,7 +112,7 @@ func (c *RESTClient) request(verb string) *rest.Request {
|
||||
serializers.StreamingSerializer = info.StreamSerializer.Serializer
|
||||
serializers.Framer = info.StreamSerializer.Framer
|
||||
}
|
||||
return rest.NewRequest(c, verb, &url.URL{Host: "localhost"}, "", config, serializers, nil, nil)
|
||||
return restclient.NewRequest(c, verb, &url.URL{Host: "localhost"}, "", config, serializers, nil, nil)
|
||||
}
|
||||
|
||||
func (c *RESTClient) Do(req *http.Request) (*http.Response, error) {
|
||||
|
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/golang/glog"
|
||||
"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"
|
||||
@@ -43,8 +44,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
pathvalidation "k8s.io/client-go/pkg/api/validation/path"
|
||||
"k8s.io/client-go/pkg/fields"
|
||||
"k8s.io/client-go/pkg/util/flowcontrol"
|
||||
restclientwatch "k8s.io/client-go/rest/watch"
|
||||
"k8s.io/client-go/tools/metrics"
|
||||
@@ -179,7 +178,7 @@ func (r *Request) Resource(resource string) *Request {
|
||||
r.err = fmt.Errorf("resource already set to %q, cannot change to %q", r.resource, resource)
|
||||
return r
|
||||
}
|
||||
if msgs := pathvalidation.IsValidPathSegmentName(resource); len(msgs) != 0 {
|
||||
if msgs := IsValidPathSegmentName(resource); len(msgs) != 0 {
|
||||
r.err = fmt.Errorf("invalid resource %q: %v", resource, msgs)
|
||||
return r
|
||||
}
|
||||
@@ -199,7 +198,7 @@ func (r *Request) SubResource(subresources ...string) *Request {
|
||||
return r
|
||||
}
|
||||
for _, s := range subresources {
|
||||
if msgs := pathvalidation.IsValidPathSegmentName(s); len(msgs) != 0 {
|
||||
if msgs := IsValidPathSegmentName(s); len(msgs) != 0 {
|
||||
r.err = fmt.Errorf("invalid subresource %q: %v", s, msgs)
|
||||
return r
|
||||
}
|
||||
@@ -221,7 +220,7 @@ func (r *Request) Name(resourceName string) *Request {
|
||||
r.err = fmt.Errorf("resource name already set to %q, cannot change to %q", r.resourceName, resourceName)
|
||||
return r
|
||||
}
|
||||
if msgs := pathvalidation.IsValidPathSegmentName(resourceName); len(msgs) != 0 {
|
||||
if msgs := IsValidPathSegmentName(resourceName); len(msgs) != 0 {
|
||||
r.err = fmt.Errorf("invalid resource name %q: %v", resourceName, msgs)
|
||||
return r
|
||||
}
|
||||
@@ -238,7 +237,7 @@ func (r *Request) Namespace(namespace string) *Request {
|
||||
r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace)
|
||||
return r
|
||||
}
|
||||
if msgs := pathvalidation.IsValidPathSegmentName(namespace); len(msgs) != 0 {
|
||||
if msgs := IsValidPathSegmentName(namespace); len(msgs) != 0 {
|
||||
r.err = fmt.Errorf("invalid namespace %q: %v", namespace, msgs)
|
||||
return r
|
||||
}
|
||||
@@ -760,10 +759,11 @@ func (r *Request) Stream() (io.ReadCloser, error) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
result := r.transformResponse(resp, req)
|
||||
if result.err != nil {
|
||||
return nil, result.err
|
||||
err := result.Error()
|
||||
if err == nil {
|
||||
err = fmt.Errorf("%d while accessing %v: %s", result.statusCode, url, string(result.body))
|
||||
}
|
||||
return nil, fmt.Errorf("%d while accessing %v: %s", result.statusCode, url, string(result.body))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1197,3 +1197,49 @@ func (r Result) Error() error {
|
||||
}
|
||||
return r.err
|
||||
}
|
||||
|
||||
// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store)
|
||||
var NameMayNotBe = []string{".", ".."}
|
||||
|
||||
// NameMayNotContain specifies substrings that cannot be used in names specified as path segments (like the REST API or etcd store)
|
||||
var NameMayNotContain = []string{"/", "%"}
|
||||
|
||||
// IsValidPathSegmentName validates the name can be safely encoded as a path segment
|
||||
func IsValidPathSegmentName(name string) []string {
|
||||
for _, illegalName := range NameMayNotBe {
|
||||
if name == illegalName {
|
||||
return []string{fmt.Sprintf(`may not be '%s'`, illegalName)}
|
||||
}
|
||||
}
|
||||
|
||||
var errors []string
|
||||
for _, illegalContent := range NameMayNotContain {
|
||||
if strings.Contains(name, illegalContent) {
|
||||
errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent))
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment
|
||||
// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid
|
||||
func IsValidPathSegmentPrefix(name string) []string {
|
||||
var errors []string
|
||||
for _, illegalContent := range NameMayNotContain {
|
||||
if strings.Contains(name, illegalContent) {
|
||||
errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent))
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
// ValidatePathSegmentName validates the name can be safely encoded as a path segment
|
||||
func ValidatePathSegmentName(name string, prefix bool) []string {
|
||||
if prefix {
|
||||
return IsValidPathSegmentPrefix(name)
|
||||
} else {
|
||||
return IsValidPathSegmentName(name)
|
||||
}
|
||||
}
|
||||
|
@@ -868,6 +868,7 @@ func TestRequestStream(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Request *Request
|
||||
Err bool
|
||||
ErrFn func(error) bool
|
||||
}{
|
||||
{
|
||||
Request: &Request{err: errors.New("bail")},
|
||||
@@ -903,6 +904,26 @@ func TestRequestStream(t *testing.T) {
|
||||
},
|
||||
Err: true,
|
||||
},
|
||||
{
|
||||
Request: &Request{
|
||||
client: clientFunc(func(req *http.Request) (*http.Response, error) {
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
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}`))),
|
||||
}, nil
|
||||
}),
|
||||
content: defaultContentConfig(),
|
||||
serializers: defaultSerializers(),
|
||||
baseURL: &url.URL{},
|
||||
},
|
||||
Err: true,
|
||||
ErrFn: func(err error) bool {
|
||||
if err.Error() == "a container name must be specified for pod kube-dns-v20-mz5cv, choose one of: [kubedns dnsmasq healthz]" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
testCase.Request.backoffMgr = &NoBackoff{}
|
||||
@@ -914,6 +935,12 @@ func TestRequestStream(t *testing.T) {
|
||||
if hasErr && body != nil {
|
||||
t.Errorf("%d: body should be nil when error is returned", i)
|
||||
}
|
||||
|
||||
if hasErr {
|
||||
if testCase.ErrFn != nil && !testCase.ErrFn(err) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user