mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-24 06:07:48 +00:00
Use content negotiation in the dynamic client.
Kubernetes-commit: 97958d96a2911c8b1df324868f4730b1c622c798
This commit is contained in:
parent
c38ce11939
commit
ee51eaf9d0
@ -21,24 +21,18 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
)
|
||||
|
||||
var watchScheme = runtime.NewScheme()
|
||||
var basicScheme = runtime.NewScheme()
|
||||
var deleteScheme = runtime.NewScheme()
|
||||
var parameterScheme = runtime.NewScheme()
|
||||
var deleteOptionsCodec = serializer.NewCodecFactory(deleteScheme)
|
||||
var dynamicParameterCodec = runtime.NewParameterCodec(parameterScheme)
|
||||
|
||||
var versionV1 = schema.GroupVersion{Version: "v1"}
|
||||
|
||||
func init() {
|
||||
metav1.AddToGroupVersion(watchScheme, versionV1)
|
||||
metav1.AddToGroupVersion(basicScheme, versionV1)
|
||||
metav1.AddToGroupVersion(parameterScheme, versionV1)
|
||||
metav1.AddToGroupVersion(deleteScheme, versionV1)
|
||||
}
|
||||
|
||||
// basicNegotiatedSerializer is used to handle discovery and error handling serialization
|
||||
@ -66,7 +60,7 @@ func (s basicNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv
|
||||
return runtime.WithVersionEncoder{
|
||||
Version: gv,
|
||||
Encoder: encoder,
|
||||
ObjectTyper: unstructuredTyper{basicScheme},
|
||||
ObjectTyper: permissiveTyper{basicScheme},
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,3 +100,25 @@ func (t unstructuredTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersio
|
||||
func (t unstructuredTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// The dynamic client has historically accepted Unstructured objects with missing or empty
|
||||
// apiVersion and/or kind as arguments to its write request methods. This typer will return the type
|
||||
// of a runtime.Unstructured with no error, even if the type is missing or empty.
|
||||
type permissiveTyper struct {
|
||||
nested runtime.ObjectTyper
|
||||
}
|
||||
|
||||
func (t permissiveTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
kinds, unversioned, err := t.nested.ObjectKinds(obj)
|
||||
if err == nil {
|
||||
return kinds, unversioned, nil
|
||||
}
|
||||
if _, ok := obj.(runtime.Unstructured); ok {
|
||||
return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
func (t permissiveTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return true
|
||||
}
|
||||
|
@ -86,11 +86,10 @@ func NewForConfig(inConfig *rest.Config) (*DynamicClient, error) {
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(inConfig *rest.Config, h *http.Client) (*DynamicClient, error) {
|
||||
config := ConfigFor(inConfig)
|
||||
// for serializing the options
|
||||
config.GroupVersion = &schema.GroupVersion{}
|
||||
config.GroupVersion = nil
|
||||
config.APIPath = "/if-you-see-this-search-for-the-break"
|
||||
|
||||
restClient, err := rest.RESTClientForConfigAndClient(config, h)
|
||||
restClient, err := rest.UnversionedRESTClientForConfigAndClient(config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -114,10 +113,6 @@ func (c *dynamicResourceClient) Namespace(ns string) ResourceInterface {
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Create(ctx context.Context, obj *unstructured.Unstructured, opts metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := ""
|
||||
if len(subresources) > 0 {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
@ -133,26 +128,17 @@ func (c *dynamicResourceClient) Create(ctx context.Context, obj *unstructured.Un
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
var out unstructured.Unstructured
|
||||
if err := c.client.client.
|
||||
Post().
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
||||
Body(outBytes).
|
||||
Body(obj).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
Do(ctx).Into(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Update(ctx context.Context, obj *unstructured.Unstructured, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
@ -167,31 +153,18 @@ func (c *dynamicResourceClient) Update(ctx context.Context, obj *unstructured.Un
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
var out unstructured.Unstructured
|
||||
if err := c.client.client.
|
||||
Put().
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
||||
Body(outBytes).
|
||||
Body(obj).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
Do(ctx).Into(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*unstructured.Unstructured, error) {
|
||||
@ -206,31 +179,18 @@ func (c *dynamicResourceClient) UpdateStatus(ctx context.Context, obj *unstructu
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
var out unstructured.Unstructured
|
||||
if err := c.client.client.
|
||||
Put().
|
||||
AbsPath(append(c.makeURLSegments(name), "status")...).
|
||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
||||
Body(outBytes).
|
||||
Body(obj).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
Do(ctx).Into(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions, subresources ...string) error {
|
||||
@ -240,16 +200,11 @@ func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts me
|
||||
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
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Delete().
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
||||
Body(deleteOptionsByte).
|
||||
Body(&opts).
|
||||
Do(ctx)
|
||||
return result.Error()
|
||||
}
|
||||
@ -259,16 +214,10 @@ func (c *dynamicResourceClient) DeleteCollection(ctx context.Context, opts metav
|
||||
return err
|
||||
}
|
||||
|
||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Delete().
|
||||
AbsPath(c.makeURLSegments("")...).
|
||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
||||
Body(deleteOptionsByte).
|
||||
Body(&opts).
|
||||
SpecificallyVersionedParams(&listOptions, dynamicParameterCodec, versionV1).
|
||||
Do(ctx)
|
||||
return result.Error()
|
||||
@ -281,20 +230,15 @@ func (c *dynamicResourceClient) Get(ctx context.Context, name string, opts metav
|
||||
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 {
|
||||
var out unstructured.Unstructured
|
||||
if err := c.client.client.
|
||||
Get().
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx).Into(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj := &unstructured.Unstructured{}
|
||||
err = runtime.DecodeInto(unstructured.UnstructuredJSONScheme, retBytes, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj, nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||
@ -319,27 +263,15 @@ func (c *dynamicResourceClient) list(ctx context.Context, opts metav1.ListOption
|
||||
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 {
|
||||
var out unstructured.UnstructuredList
|
||||
if err := c.client.client.
|
||||
Get().
|
||||
AbsPath(c.makeURLSegments("")...).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx).Into(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list, ok := uncastObj.(*unstructured.UnstructuredList); ok {
|
||||
return list, nil
|
||||
}
|
||||
|
||||
list, err := uncastObj.(*unstructured.Unstructured).ToList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
// watchList establishes a watch stream with the server and returns an unstructured list.
|
||||
@ -380,24 +312,16 @@ func (c *dynamicResourceClient) Patch(ctx context.Context, name string, pt types
|
||||
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := c.client.client.
|
||||
var out unstructured.Unstructured
|
||||
if err := c.client.client.
|
||||
Patch(pt).
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
Body(data).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
Do(ctx).Into(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
@ -435,12 +359,13 @@ func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *uns
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
var out unstructured.Unstructured
|
||||
if err := runtime.DecodeInto(unstructured.UnstructuredJSONScheme, retBytes, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions) (*unstructured.Unstructured, error) {
|
||||
return c.Apply(ctx, name, obj, opts, "status")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user