From 7e9fc247fefd9b5082563ee911f37cecb1008675 Mon Sep 17 00:00:00 2001 From: David Eads Date: Wed, 10 Jan 2018 12:11:17 -0500 Subject: [PATCH] manuallly handle encoding and decoding in the scale client Kubernetes-commit: 877143e547921747d9fd14e2af776b34663d37dc --- scale/client.go | 47 +++++++++++++++++++++++++++++++++++------------ scale/util.go | 19 +++++++++++++++++++ 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/scale/client.go b/scale/client.go index 3f85197a..07c60986 100644 --- a/scale/client.go +++ b/scale/client.go @@ -21,6 +21,7 @@ import ( autoscaling "k8s.io/api/autoscaling/v1" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/dynamic" @@ -129,21 +130,29 @@ func (c *namespacedScaleClient) Get(resource schema.GroupResource, name string) return nil, fmt.Errorf("unable to get client for %s: %v", resource.String(), err) } - rawObj, err := c.client.clientBase.Get(). + result := c.client.clientBase.Get(). AbsPath(path). Namespace(c.namespace). Resource(gvr.Resource). Name(name). SubResource("scale"). - Do(). - Get() + Do() + if err := result.Error(); err != nil { + return nil, fmt.Errorf("could not fetch the scale for %s %s: %v", resource.String(), name, err) + } + scaleBytes, err := result.Raw() + if err != nil { + return nil, err + } + decoder := scaleConverter.codecs.UniversalDecoder(scaleConverter.ScaleVersions()...) + rawScaleObj, err := runtime.Decode(decoder, scaleBytes) if err != nil { return nil, err } // convert whatever this is to autoscaling/v1.Scale - scaleObj, err := scaleConverter.ConvertToVersion(rawObj, autoscaling.SchemeGroupVersion) + scaleObj, err := scaleConverter.ConvertToVersion(rawScaleObj, autoscaling.SchemeGroupVersion) if err != nil { return nil, fmt.Errorf("received an object from a /scale endpoint which was not convertible to autoscaling Scale: %v", err) } @@ -158,7 +167,7 @@ func (c *namespacedScaleClient) Update(resource schema.GroupResource, scale *aut } // Currently, a /scale endpoint can receive and return different scale types. - // Until we hvae support for the alternative API representations proposal, + // Until we have support for the alternative API representations proposal, // we need to deal with sending and accepting differnet API versions. // figure out what scale we actually need here @@ -170,25 +179,39 @@ func (c *namespacedScaleClient) Update(resource schema.GroupResource, scale *aut // convert this to whatever this endpoint wants scaleUpdate, err := scaleConverter.ConvertToVersion(scale, desiredGVK.GroupVersion()) if err != nil { - return nil, fmt.Errorf("could not convert scale update to internal Scale: %v", err) + return nil, fmt.Errorf("could not convert scale update to external Scale: %v", err) + } + encoder := scaleConverter.codecs.LegacyCodec(desiredGVK.GroupVersion()) + scaleUpdateBytes, err := runtime.Encode(encoder, scaleUpdate) + if err != nil { + return nil, fmt.Errorf("could not encode scale update to external Scale: %v", err) } - rawObj, err := c.client.clientBase.Put(). + result := c.client.clientBase.Put(). AbsPath(path). Namespace(c.namespace). Resource(gvr.Resource). Name(scale.Name). SubResource("scale"). - Body(scaleUpdate). - Do(). - Get() + Body(scaleUpdateBytes). + Do() + if err := result.Error(); err != nil { + panic(err) + return nil, fmt.Errorf("could not update the scale for %s %s: %v", resource.String(), scale.Name, err) + } + scaleBytes, err := result.Raw() if err != nil { - return nil, fmt.Errorf("could not fetch the scale for %s %s: %v", resource.String(), scale.Name, err) + return nil, err + } + decoder := scaleConverter.codecs.UniversalDecoder(scaleConverter.ScaleVersions()...) + rawScaleObj, err := runtime.Decode(decoder, scaleBytes) + if err != nil { + return nil, err } // convert whatever this is back to autoscaling/v1.Scale - scaleObj, err := scaleConverter.ConvertToVersion(rawObj, autoscaling.SchemeGroupVersion) + scaleObj, err := scaleConverter.ConvertToVersion(rawScaleObj, autoscaling.SchemeGroupVersion) if err != nil { return nil, fmt.Errorf("received an object from a /scale endpoint which was not convertible to autoscaling Scale: %v", err) } diff --git a/scale/util.go b/scale/util.go index 9eb10853..46b5c4d1 100644 --- a/scale/util.go +++ b/scale/util.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/discovery" scalescheme "k8s.io/client-go/scale/scheme" scaleappsint "k8s.io/client-go/scale/scheme/appsint" @@ -124,6 +125,7 @@ func NewDiscoveryScaleKindResolver(client discovery.ServerResourcesInterface) Sc // ScaleConverter knows how to convert between external scale versions. type ScaleConverter struct { scheme *runtime.Scheme + codecs serializer.CodecFactory internalVersioner runtime.GroupVersioner } @@ -141,6 +143,7 @@ func NewScaleConverter() *ScaleConverter { return &ScaleConverter{ scheme: scheme, + codecs: serializer.NewCodecFactory(scheme), internalVersioner: runtime.NewMultiGroupVersioner( scalescheme.SchemeGroupVersion, schema.GroupKind{Group: scaleext.GroupName, Kind: "Scale"}, @@ -156,6 +159,22 @@ func (c *ScaleConverter) Scheme() *runtime.Scheme { return c.scheme } +func (c *ScaleConverter) Codecs() serializer.CodecFactory { + return c.codecs +} + +func (c *ScaleConverter) ScaleVersions() []schema.GroupVersion { + return []schema.GroupVersion{ + scaleautoscaling.SchemeGroupVersion, + scalescheme.SchemeGroupVersion, + scaleext.SchemeGroupVersion, + scaleextint.SchemeGroupVersion, + scaleappsint.SchemeGroupVersion, + scaleappsv1beta1.SchemeGroupVersion, + scaleappsv1beta2.SchemeGroupVersion, + } +} + // ConvertToVersion converts the given *external* input object to the given output *external* output group-version. func (c *ScaleConverter) ConvertToVersion(in runtime.Object, outVersion schema.GroupVersion) (runtime.Object, error) { scaleInt, err := c.scheme.ConvertToVersion(in, c.internalVersioner)