mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-24 14:12:18 +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/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
var watchScheme = runtime.NewScheme()
|
|
||||||
var basicScheme = runtime.NewScheme()
|
var basicScheme = runtime.NewScheme()
|
||||||
var deleteScheme = runtime.NewScheme()
|
|
||||||
var parameterScheme = runtime.NewScheme()
|
var parameterScheme = runtime.NewScheme()
|
||||||
var deleteOptionsCodec = serializer.NewCodecFactory(deleteScheme)
|
|
||||||
var dynamicParameterCodec = runtime.NewParameterCodec(parameterScheme)
|
var dynamicParameterCodec = runtime.NewParameterCodec(parameterScheme)
|
||||||
|
|
||||||
var versionV1 = schema.GroupVersion{Version: "v1"}
|
var versionV1 = schema.GroupVersion{Version: "v1"}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
metav1.AddToGroupVersion(watchScheme, versionV1)
|
|
||||||
metav1.AddToGroupVersion(basicScheme, versionV1)
|
metav1.AddToGroupVersion(basicScheme, versionV1)
|
||||||
metav1.AddToGroupVersion(parameterScheme, versionV1)
|
metav1.AddToGroupVersion(parameterScheme, versionV1)
|
||||||
metav1.AddToGroupVersion(deleteScheme, versionV1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// basicNegotiatedSerializer is used to handle discovery and error handling serialization
|
// 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{
|
return runtime.WithVersionEncoder{
|
||||||
Version: gv,
|
Version: gv,
|
||||||
Encoder: encoder,
|
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 {
|
func (t unstructuredTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||||
return true
|
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.
|
// Note the http client provided takes precedence over the configured transport values.
|
||||||
func NewForConfigAndClient(inConfig *rest.Config, h *http.Client) (*DynamicClient, error) {
|
func NewForConfigAndClient(inConfig *rest.Config, h *http.Client) (*DynamicClient, error) {
|
||||||
config := ConfigFor(inConfig)
|
config := ConfigFor(inConfig)
|
||||||
// for serializing the options
|
config.GroupVersion = nil
|
||||||
config.GroupVersion = &schema.GroupVersion{}
|
|
||||||
config.APIPath = "/if-you-see-this-search-for-the-break"
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
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 := ""
|
name := ""
|
||||||
if len(subresources) > 0 {
|
if len(subresources) > 0 {
|
||||||
accessor, err := meta.Accessor(obj)
|
accessor, err := meta.Accessor(obj)
|
||||||
@ -133,26 +128,17 @@ func (c *dynamicResourceClient) Create(ctx context.Context, obj *unstructured.Un
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := c.client.client.
|
var out unstructured.Unstructured
|
||||||
|
if err := c.client.client.
|
||||||
Post().
|
Post().
|
||||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
Body(obj).
|
||||||
Body(outBytes).
|
|
||||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||||
Do(ctx)
|
Do(ctx).Into(&out); err != nil {
|
||||||
if err := result.Error(); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
retBytes, err := result.Raw()
|
return &out, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return uncastObj.(*unstructured.Unstructured), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Update(ctx context.Context, obj *unstructured.Unstructured, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
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 {
|
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||||
return nil, err
|
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().
|
Put().
|
||||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
Body(obj).
|
||||||
Body(outBytes).
|
|
||||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||||
Do(ctx)
|
Do(ctx).Into(&out); err != nil {
|
||||||
if err := result.Error(); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
retBytes, err := result.Raw()
|
return &out, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return uncastObj.(*unstructured.Unstructured), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*unstructured.Unstructured, error) {
|
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 {
|
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||||
return nil, err
|
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().
|
Put().
|
||||||
AbsPath(append(c.makeURLSegments(name), "status")...).
|
AbsPath(append(c.makeURLSegments(name), "status")...).
|
||||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
Body(obj).
|
||||||
Body(outBytes).
|
|
||||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||||
Do(ctx)
|
Do(ctx).Into(&out); err != nil {
|
||||||
if err := result.Error(); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
retBytes, err := result.Raw()
|
return &out, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return uncastObj.(*unstructured.Unstructured), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions, subresources ...string) error {
|
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 {
|
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := c.client.client.
|
result := c.client.client.
|
||||||
Delete().
|
Delete().
|
||||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
Body(&opts).
|
||||||
Body(deleteOptionsByte).
|
|
||||||
Do(ctx)
|
Do(ctx)
|
||||||
return result.Error()
|
return result.Error()
|
||||||
}
|
}
|
||||||
@ -259,16 +214,10 @@ func (c *dynamicResourceClient) DeleteCollection(ctx context.Context, opts metav
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := c.client.client.
|
result := c.client.client.
|
||||||
Delete().
|
Delete().
|
||||||
AbsPath(c.makeURLSegments("")...).
|
AbsPath(c.makeURLSegments("")...).
|
||||||
SetHeader("Content-Type", runtime.ContentTypeJSON).
|
Body(&opts).
|
||||||
Body(deleteOptionsByte).
|
|
||||||
SpecificallyVersionedParams(&listOptions, dynamicParameterCodec, versionV1).
|
SpecificallyVersionedParams(&listOptions, dynamicParameterCodec, versionV1).
|
||||||
Do(ctx)
|
Do(ctx)
|
||||||
return result.Error()
|
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 {
|
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := c.client.client.Get().AbsPath(append(c.makeURLSegments(name), subresources...)...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx)
|
var out unstructured.Unstructured
|
||||||
if err := result.Error(); err != nil {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
retBytes, err := result.Raw()
|
return &out, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
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 {
|
if err := validateNamespaceWithOptionalName(c.namespace); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := c.client.client.Get().AbsPath(c.makeURLSegments("")...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx)
|
var out unstructured.UnstructuredList
|
||||||
if err := result.Error(); err != nil {
|
if err := c.client.client.
|
||||||
|
Get().
|
||||||
|
AbsPath(c.makeURLSegments("")...).
|
||||||
|
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||||
|
Do(ctx).Into(&out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
retBytes, err := result.Raw()
|
return &out, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchList establishes a watch stream with the server and returns an unstructured list.
|
// 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 {
|
if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := c.client.client.
|
var out unstructured.Unstructured
|
||||||
|
if err := c.client.client.
|
||||||
Patch(pt).
|
Patch(pt).
|
||||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||||
Body(data).
|
Body(data).
|
||||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||||
Do(ctx)
|
Do(ctx).Into(&out); err != nil {
|
||||||
if err := result.Error(); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
retBytes, err := result.Raw()
|
return &out, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return uncastObj.(*unstructured.Unstructured), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
var out unstructured.Unstructured
|
||||||
if err != nil {
|
if err := runtime.DecodeInto(unstructured.UnstructuredJSONScheme, retBytes, &out); err != nil {
|
||||||
return nil, err
|
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) {
|
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")
|
return c.Apply(ctx, name, obj, opts, "status")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user