add DirectCodec; use it in release_1_3 clientset

pull/6/head
Chao Xu 2016-05-24 23:19:46 -07:00
parent 5762ebfc63
commit f32f3966d6
13 changed files with 126 additions and 117 deletions

View File

@ -61,6 +61,7 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
const pkgRESTClient = "k8s.io/kubernetes/pkg/client/restclient"
const pkgRegistered = "k8s.io/kubernetes/pkg/apimachinery/registered"
const pkgAPI = "k8s.io/kubernetes/pkg/api"
const pkgSerializer = "k8s.io/kubernetes/pkg/runtime/serializer"
apiPath := func(group string) string {
if group == "core" {
return `"/api"`
@ -93,6 +94,7 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
"GroupOrDie": c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "GroupOrDie"}),
"apiPath": apiPath(g.group),
"codecs": c.Universe.Variable(types.Name{Package: pkgAPI, Name: "Codecs"}),
"directCodecFactory": c.Universe.Variable(types.Name{Package: pkgSerializer, Name: "DirectCodecFactory"}),
"Errorf": c.Universe.Variable(types.Name{Package: "fmt", Name: "Errorf"}),
}
sw.Do(groupInterfaceTemplate, m)
@ -240,7 +242,7 @@ func setConfigDefaults(config *$.Config|raw$) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = $.codecs|raw$
config.NegotiatedSerializer = $.directCodecFactory|raw${CodecFactory: $.codecs|raw$}
if config.QPS == 0 {
config.QPS = 5

View File

@ -20,6 +20,7 @@ import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type CoreInterface interface {
@ -80,7 +81,7 @@ func setConfigDefaults(config *restclient.Config) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
if config.QPS == 0 {
config.QPS = 5

View File

@ -20,6 +20,7 @@ import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type FederationInterface interface {
@ -80,7 +81,7 @@ func setConfigDefaults(config *restclient.Config) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
if config.QPS == 0 {
config.QPS = 5

View File

@ -20,6 +20,7 @@ import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type AutoscalingInterface interface {
@ -80,7 +81,7 @@ func setConfigDefaults(config *restclient.Config) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
if config.QPS == 0 {
config.QPS = 5

View File

@ -20,6 +20,7 @@ import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type BatchInterface interface {
@ -80,7 +81,7 @@ func setConfigDefaults(config *restclient.Config) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
if config.QPS == 0 {
config.QPS = 5

View File

@ -20,6 +20,7 @@ import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type CoreInterface interface {
@ -150,7 +151,7 @@ func setConfigDefaults(config *restclient.Config) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
if config.QPS == 0 {
config.QPS = 5

View File

@ -20,6 +20,7 @@ import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type ExtensionsInterface interface {
@ -120,7 +121,7 @@ func setConfigDefaults(config *restclient.Config) error {
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
if config.QPS == 0 {
config.QPS = 5

View File

@ -1,50 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package release_1_2
import (
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_2"
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_2/typed/core/v1"
v1beta1extensions "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_2/typed/extensions/v1beta1"
"k8s.io/kubernetes/pkg/client/typed/discovery"
"k8s.io/kubernetes/pkg/client/unversioned"
)
// FromUnversionedClient adapts a unversioned.Client to a release_1_2.Clientset.
// This function is temporary. We will remove it when everyone has moved to using
// Clientset. New code should NOT use this function.
func FromUnversionedClient(c *unversioned.Client) *release_1_2.Clientset {
var clientset release_1_2.Clientset
if c != nil {
clientset.CoreClient = v1core.New(c.RESTClient)
} else {
clientset.CoreClient = v1core.New(nil)
}
if c != nil && c.ExtensionsClient != nil {
clientset.ExtensionsClient = v1beta1extensions.New(c.ExtensionsClient.RESTClient)
} else {
clientset.ExtensionsClient = v1beta1extensions.New(nil)
}
if c != nil && c.DiscoveryClient != nil {
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c.DiscoveryClient.RESTClient)
} else {
clientset.DiscoveryClient = discovery.NewDiscoveryClient(nil)
}
return &clientset
}

View File

@ -1,50 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package release_1_3
import (
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3"
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3/typed/core/v1"
v1beta1extensions "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3/typed/extensions/v1beta1"
"k8s.io/kubernetes/pkg/client/typed/discovery"
"k8s.io/kubernetes/pkg/client/unversioned"
)
// FromUnversionedClient adapts a unversioned.Client to a release_1_3.Clientset.
// This function is temporary. We will remove it when everyone has moved to using
// Clientset. New code should NOT use this function.
func FromUnversionedClient(c *unversioned.Client) *release_1_3.Clientset {
var clientset release_1_3.Clientset
if c != nil {
clientset.CoreClient = v1core.New(c.RESTClient)
} else {
clientset.CoreClient = v1core.New(nil)
}
if c != nil && c.ExtensionsClient != nil {
clientset.ExtensionsClient = v1beta1extensions.New(c.ExtensionsClient.RESTClient)
} else {
clientset.ExtensionsClient = v1beta1extensions.New(nil)
}
if c != nil && c.DiscoveryClient != nil {
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c.DiscoveryClient.RESTClient)
} else {
clientset.DiscoveryClient = discovery.NewDiscoveryClient(nil)
}
return &clientset
}

View File

@ -17,6 +17,8 @@ limitations under the License.
package serializer
import (
"io"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer/json"
@ -308,3 +310,55 @@ func (f CodecFactory) SerializerForFileExtension(extension string) (runtime.Seri
}
return nil, false
}
// DirectCodecFactory provides methods for retrieving "DirectCodec"s, which do not do conversion.
type DirectCodecFactory struct {
CodecFactory
}
// EncoderForVersion returns an encoder that does not do conversion. gv is ignored.
func (f DirectCodecFactory) EncoderForVersion(serializer runtime.Encoder, gv unversioned.GroupVersion) runtime.Encoder {
return DirectCodec{
runtime.NewCodec(serializer, nil),
f.CodecFactory.scheme,
}
}
// DecoderToVersion returns an decoder that does not do conversion. gv is ignored.
func (f DirectCodecFactory) DecoderToVersion(serializer runtime.Decoder, gv unversioned.GroupVersion) runtime.Decoder {
return DirectCodec{
runtime.NewCodec(nil, serializer),
nil,
}
}
// DirectCodec is a codec that does not do conversion. It sets the gvk during serialization, and removes the gvk during deserialization.
type DirectCodec struct {
runtime.Serializer
runtime.ObjectTyper
}
// EncodeToStream does not do conversion. It sets the gvk during serialization. overrides are ignored.
func (c DirectCodec) EncodeToStream(obj runtime.Object, stream io.Writer, overrides ...unversioned.GroupVersion) error {
gvks, _, err := c.ObjectTyper.ObjectKinds(obj)
if err != nil {
return err
}
kind := obj.GetObjectKind()
oldGVK := kind.GroupVersionKind()
kind.SetGroupVersionKind(gvks[0])
err = c.Serializer.EncodeToStream(obj, stream, overrides...)
kind.SetGroupVersionKind(oldGVK)
return err
}
// Decode does not do conversion. It removes the gvk during deserialization.
func (c DirectCodec) Decode(data []byte, defaults *unversioned.GroupVersionKind, into runtime.Object) (runtime.Object, *unversioned.GroupVersionKind, error) {
obj, gvk, err := c.Serializer.Decode(data, defaults, into)
if obj != nil {
kind := obj.GetObjectKind()
// clearing the gvk is just a convention of a codec
kind.SetGroupVersionKind(unversioned.GroupVersionKind{})
}
return obj, gvk, err
}

View File

@ -398,3 +398,49 @@ func TestBadJSONRejection(t *testing.T) {
t.Errorf("Did not give error for empty data")
}
}
// Returns a new Scheme set up with the test objects needed by TestDirectCodec.
func GetDirectCodecTestScheme() *runtime.Scheme {
internalGV := unversioned.GroupVersion{Version: runtime.APIVersionInternal}
externalGV := unversioned.GroupVersion{Version: "v1"}
s := runtime.NewScheme()
// Ordinarily, we wouldn't add TestType2, but because this is a test and
// both types are from the same package, we need to get it into the system
// so that converter will match it with ExternalType2.
s.AddKnownTypes(internalGV, &TestType1{})
s.AddKnownTypes(externalGV, &ExternalTestType1{})
s.AddUnversionedTypes(externalGV, &unversioned.Status{})
return s
}
func TestDirectCodec(t *testing.T) {
s := GetDirectCodecTestScheme()
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
serializer, _ := cf.SerializerForFileExtension("json")
df := DirectCodecFactory{cf}
ignoredGV, err := unversioned.ParseGroupVersion("ignored group/ignored version")
if err != nil {
t.Fatal(err)
}
directEncoder := df.EncoderForVersion(serializer, ignoredGV)
directDecoder := df.DecoderToVersion(serializer, ignoredGV)
out, err := runtime.Encode(directEncoder, &ExternalTestType1{}, ignoredGV)
if err != nil {
t.Fatal(err)
}
if string(out) != `{"myVersionKey":"v1","myKindKey":"ExternalTestType1"}`+"\n" {
t.Fatal(string(out))
}
a, _, err := directDecoder.Decode(out, nil, nil)
e := &ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{
APIVersion: "v1",
ObjectKind: "ExternalTestType1",
},
}
if !semantic.DeepEqual(e, a) {
t.Fatalf("expect %v, got %v", e, a)
}
}

View File

@ -31,8 +31,6 @@ import (
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_2"
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3"
client "k8s.io/kubernetes/pkg/client/unversioned"
adapter_1_2 "k8s.io/kubernetes/pkg/client/unversioned/adapters/release_1_2"
adapter_1_3 "k8s.io/kubernetes/pkg/client/unversioned/adapters/release_1_3"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/metrics"
@ -130,7 +128,6 @@ func (f *Framework) BeforeEach() {
// The fact that we need this feels like a bug in ginkgo.
// https://github.com/onsi/ginkgo/issues/222
f.cleanupHandle = AddCleanupAction(f.AfterEach)
if f.Client == nil {
By("Creating a kubernetes client")
config, err := LoadConfig()
@ -143,11 +140,12 @@ func (f *Framework) BeforeEach() {
c, err := loadClientFromConfig(config)
Expect(err).NotTo(HaveOccurred())
f.Client = c
f.Clientset_1_2, err = release_1_2.NewForConfig(config)
Expect(err).NotTo(HaveOccurred())
f.Clientset_1_3, err = release_1_3.NewForConfig(config)
Expect(err).NotTo(HaveOccurred())
}
f.Clientset_1_2 = adapter_1_2.FromUnversionedClient(f.Client)
f.Clientset_1_3 = adapter_1_3.FromUnversionedClient(f.Client)
if f.federated && f.FederationClient == nil {
By("Creating a federated kubernetes client")
var err error

View File

@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/watch"
@ -74,7 +75,7 @@ func observePodCreation(w watch.Interface) {
}
}
func observePodDeletion(w watch.Interface) (lastPod *api.Pod) {
func observeObjectDeletion(w watch.Interface) (obj runtime.Object) {
deleted := false
timeout := false
timer := time.After(60 * time.Second)
@ -82,7 +83,7 @@ func observePodDeletion(w watch.Interface) (lastPod *api.Pod) {
select {
case event, _ := <-w.ResultChan():
if event.Type == watch.Deleted {
lastPod = event.Object.(*api.Pod)
obj = event.Object
deleted = true
}
case <-timer:
@ -155,7 +156,8 @@ var _ = framework.KubeDescribe("Generated release_1_2 clientset", func() {
}
By("verifying pod deletion was observed")
lastPod := observePodDeletion(w)
obj := observeObjectDeletion(w)
lastPod := obj.(*api.Pod)
Expect(lastPod.DeletionTimestamp).ToNot(BeNil())
Expect(lastPod.Spec.TerminationGracePeriodSeconds).ToNot(BeZero())
@ -228,7 +230,8 @@ var _ = framework.KubeDescribe("Generated release_1_3 clientset", func() {
}
By("verifying pod deletion was observed")
lastPod := observePodDeletion(w)
obj := observeObjectDeletion(w)
lastPod := obj.(*v1.Pod)
Expect(lastPod.DeletionTimestamp).ToNot(BeNil())
Expect(lastPod.Spec.TerminationGracePeriodSeconds).ToNot(BeZero())