mirror of https://github.com/k3s-io/k3s
Make runtime less global for Codec
* Make Codec separate from Scheme * Move EncodeOrDie off Scheme to take a Codec * Make Copy work without a Codec * Create a "latest" package that imports all versions and sets global defaults for "most recent encoding" * v1beta1 is the current "latest", v1beta2 exists * Kill DefaultCodec, replace it with "latest.Codec" * This updates the client and etcd to store the latest known version * EmbeddedObject is per schema and per package now * Move runtime.DefaultScheme to api.Scheme * Split out WatchEvent since it's not an API object today, treat it like a special object in api * Kill DefaultResourceVersioner, instead place it on "latest" (as the package that understands all packages) * Move objDiff to runtime.ObjectDiffpull/6/head
parent
154a91cd33
commit
61e3ce7ddc
|
@ -29,6 +29,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
|
||||
|
@ -206,7 +207,7 @@ func runAtomicPutTest(c *client.Client) {
|
|||
var svc api.Service
|
||||
err := c.Post().Path("services").Body(
|
||||
&api.Service{
|
||||
JSONBase: api.JSONBase{ID: "atomicservice", APIVersion: "v1beta1"},
|
||||
JSONBase: api.JSONBase{ID: "atomicservice", APIVersion: latest.Version},
|
||||
Port: 12345,
|
||||
Labels: map[string]string{
|
||||
"name": "atomicService",
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/golang/glog"
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 api
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Codec is the identity codec for this package - it can only convert itself
|
||||
// to itself.
|
||||
var Codec = runtime.CodecFor(Scheme, "")
|
||||
|
||||
// EmbeddedObject implements a Codec specific version of an
|
||||
// embedded object.
|
||||
type EmbeddedObject struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
|
||||
obj, err := runtime.CodecUnmarshalJSON(Codec, b)
|
||||
a.Object = obj
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
|
||||
return runtime.CodecMarshalJSON(Codec, a.Object)
|
||||
}
|
||||
|
||||
// SetYAML implements the yaml.Setter interface.
|
||||
func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
||||
obj, ok := runtime.CodecSetYAML(Codec, tag, value)
|
||||
a.Object = obj
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetYAML implements the yaml.Getter interface.
|
||||
func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
|
||||
return runtime.CodecGetYAML(Codec, a.Object)
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 latest defines the default output serializations that code should
|
||||
// use and imports the required schemas. It also ensures all previously known
|
||||
// and supported API versions are available for conversion.
|
||||
package latest
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 latest
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Version is the string that represents the current external default version
|
||||
var Version = "v1beta1"
|
||||
|
||||
// Codec is the default codec for serializing output that should use
|
||||
// the latest supported version. Use this Codec when writing to
|
||||
// disk, a data store that is not dynamically versioned, or in tests.
|
||||
// This codec can decode any object that Kubernetes is aware of.
|
||||
var Codec = v1beta1.Codec
|
||||
|
||||
// ResourceVersioner describes a default versioner that can handle all types
|
||||
// of versioning.
|
||||
// TODO: when versioning changes, make this part of each API definition.
|
||||
var ResourceVersioner = runtime.NewJSONBaseResourceVersioner()
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 latest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
internal "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
"github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
// apiObjectFuzzer can randomly populate api objects.
|
||||
var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
|
||||
func(j *internal.JSONBase, c fuzz.Continue) {
|
||||
// We have to customize the randomization of JSONBases because their
|
||||
// APIVersion and Kind must remain blank in memory.
|
||||
j.APIVersion = ""
|
||||
j.Kind = ""
|
||||
j.ID = c.RandString()
|
||||
// TODO: Fix JSON/YAML packages and/or write custom encoding
|
||||
// for uint64's. Somehow the LS *byte* of this is lost, but
|
||||
// only when all 8 bytes are set.
|
||||
j.ResourceVersion = c.RandUint64() >> 8
|
||||
j.SelfLink = c.RandString()
|
||||
|
||||
var sec, nsec int64
|
||||
c.Fuzz(&sec)
|
||||
c.Fuzz(&nsec)
|
||||
j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy()
|
||||
},
|
||||
func(intstr *util.IntOrString, c fuzz.Continue) {
|
||||
// util.IntOrString will panic if its kind is set wrong.
|
||||
if c.RandBool() {
|
||||
intstr.Kind = util.IntstrInt
|
||||
intstr.IntVal = int(c.RandUint64())
|
||||
intstr.StrVal = ""
|
||||
} else {
|
||||
intstr.Kind = util.IntstrString
|
||||
intstr.IntVal = 0
|
||||
intstr.StrVal = c.RandString()
|
||||
}
|
||||
},
|
||||
func(u64 *uint64, c fuzz.Continue) {
|
||||
// TODO: uint64's are NOT handled right.
|
||||
*u64 = c.RandUint64() >> 8
|
||||
},
|
||||
func(pb map[docker.Port][]docker.PortBinding, c fuzz.Continue) {
|
||||
// This is necessary because keys with nil values get omitted.
|
||||
// TODO: Is this a bug?
|
||||
pb[docker.Port(c.RandString())] = []docker.PortBinding{
|
||||
{c.RandString(), c.RandString()},
|
||||
{c.RandString(), c.RandString()},
|
||||
}
|
||||
},
|
||||
func(pm map[string]docker.PortMapping, c fuzz.Continue) {
|
||||
// This is necessary because keys with nil values get omitted.
|
||||
// TODO: Is this a bug?
|
||||
pm[c.RandString()] = docker.PortMapping{
|
||||
c.RandString(): c.RandString(),
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
func TestInternalRoundTrip(t *testing.T) {
|
||||
latest := "v1beta2"
|
||||
|
||||
for k, _ := range internal.Scheme.KnownTypes("") {
|
||||
obj, err := internal.Scheme.New("", k)
|
||||
if err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
continue
|
||||
}
|
||||
apiObjectFuzzer.Fuzz(obj)
|
||||
|
||||
newer, err := internal.Scheme.New(latest, k)
|
||||
if err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := internal.Scheme.Convert(obj, newer); err != nil {
|
||||
t.Errorf("unable to convert %#v to %#v: %v", obj, newer, err)
|
||||
}
|
||||
|
||||
actual, err := internal.Scheme.New("", k)
|
||||
if err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := internal.Scheme.Convert(newer, actual); err != nil {
|
||||
t.Errorf("unable to convert %#v to %#v: %v", newer, actual, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(obj, actual) {
|
||||
t.Errorf("%s: diff %s", k, runtime.ObjectDiff(obj, actual))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceVersioner(t *testing.T) {
|
||||
pod := internal.Pod{JSONBase: internal.JSONBase{ResourceVersion: 10}}
|
||||
version, err := ResourceVersioner.ResourceVersion(&pod)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if version != 10 {
|
||||
t.Errorf("unexpected version %d", version)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodec(t *testing.T) {
|
||||
pod := internal.Pod{}
|
||||
data, err := Codec.Encode(&pod)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
other := internal.Pod{}
|
||||
if err := json.Unmarshal(data, &other); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if other.APIVersion != Version || other.Kind != "Pod" {
|
||||
t.Errorf("unexpected unmarshalled object %#v", other)
|
||||
}
|
||||
}
|
|
@ -20,8 +20,10 @@ import (
|
|||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
func init() {
|
||||
runtime.DefaultScheme.AddKnownTypes("",
|
||||
Scheme.AddKnownTypes("",
|
||||
&PodList{},
|
||||
&Pod{},
|
||||
&ReplicationControllerList{},
|
||||
|
|
|
@ -17,14 +17,14 @@ limitations under the License.
|
|||
package api_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
|
@ -105,27 +105,7 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
|
|||
},
|
||||
)
|
||||
|
||||
func objDiff(a, b runtime.Object) string {
|
||||
ab, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
panic("a")
|
||||
}
|
||||
bb, err := json.Marshal(b)
|
||||
if err != nil {
|
||||
panic("b")
|
||||
}
|
||||
return util.StringDiff(string(ab), string(bb))
|
||||
|
||||
// An alternate diff attempt, in case json isn't showing you
|
||||
// the difference. (reflect.DeepEqual makes a distinction between
|
||||
// nil and empty slices, for example.)
|
||||
return util.StringDiff(
|
||||
fmt.Sprintf("%#v", a),
|
||||
fmt.Sprintf("%#v", b),
|
||||
)
|
||||
}
|
||||
|
||||
func runTest(t *testing.T, source runtime.Object) {
|
||||
func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) {
|
||||
name := reflect.TypeOf(source).Elem().Name()
|
||||
apiObjectFuzzer.Fuzz(source)
|
||||
j, err := runtime.FindJSONBase(source)
|
||||
|
@ -135,30 +115,30 @@ func runTest(t *testing.T, source runtime.Object) {
|
|||
j.SetKind("")
|
||||
j.SetAPIVersion("")
|
||||
|
||||
data, err := latest.Codec.Encode(source)
|
||||
data, err := codec.Encode(source)
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v (%#v)", name, err, source)
|
||||
return
|
||||
}
|
||||
|
||||
obj2, err := latest.Codec.Decode(data)
|
||||
obj2, err := codec.Decode(data)
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v", name, err)
|
||||
return
|
||||
} else {
|
||||
if !reflect.DeepEqual(source, obj2) {
|
||||
t.Errorf("1: %v: diff: %v", name, objDiff(source, obj2))
|
||||
t.Errorf("1: %v: diff: %v", name, runtime.ObjectDiff(source, obj2))
|
||||
return
|
||||
}
|
||||
}
|
||||
obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface().(runtime.Object)
|
||||
err = latest.Codec.DecodeInto(data, obj3)
|
||||
err = codec.DecodeInto(data, obj3)
|
||||
if err != nil {
|
||||
t.Errorf("2: %v: %v", name, err)
|
||||
return
|
||||
} else {
|
||||
if !reflect.DeepEqual(source, obj3) {
|
||||
t.Errorf("3: %v: diff: %v", name, objDiff(source, obj3))
|
||||
t.Errorf("3: %v: diff: %v", name, runtime.ObjectDiff(source, obj3))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +164,8 @@ func TestTypes(t *testing.T) {
|
|||
for _, item := range table {
|
||||
// Try a few times, since runTest uses random values.
|
||||
for i := 0; i < *fuzzIters; i++ {
|
||||
runTest(t, item)
|
||||
runTest(t, v1beta1.Codec, item)
|
||||
runTest(t, v1beta2.Codec, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,7 @@ limitations under the License.
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
|
@ -623,13 +621,3 @@ type ServerOpList struct {
|
|||
}
|
||||
|
||||
func (*ServerOpList) IsAnAPIObject() {}
|
||||
|
||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||
type WatchEvent struct {
|
||||
// The type of the watch event; added, modified, or deleted.
|
||||
Type watch.EventType
|
||||
|
||||
// For added or modified objects, this is the new object; for deleted objects,
|
||||
// it's the state of the object immediately prior to its deletion.
|
||||
Object runtime.EmbeddedObject
|
||||
}
|
||||
|
|
|
@ -17,14 +17,13 @@ limitations under the License.
|
|||
package v1beta1
|
||||
|
||||
import (
|
||||
// Alias this so it can be easily changed when we cut the next version.
|
||||
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
runtime.DefaultScheme.AddConversionFuncs(
|
||||
newer.Scheme.AddConversionFuncs(
|
||||
// EnvVar's Key is deprecated in favor of Name.
|
||||
func(in *newer.EnvVar, out *EnvVar, s conversion.Scope) error {
|
||||
out.Value = in.Value
|
||||
|
@ -81,3 +80,33 @@ func init() {
|
|||
)
|
||||
|
||||
}
|
||||
|
||||
// EmbeddedObject implements a Codec specific version of an
|
||||
// embedded object.
|
||||
type EmbeddedObject struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
|
||||
obj, err := runtime.CodecUnmarshalJSON(Codec, b)
|
||||
a.Object = obj
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
|
||||
return runtime.CodecMarshalJSON(Codec, a.Object)
|
||||
}
|
||||
|
||||
// SetYAML implements the yaml.Setter interface.
|
||||
func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
||||
obj, ok := runtime.CodecSetYAML(Codec, tag, value)
|
||||
a.Object = obj
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetYAML implements the yaml.Getter interface.
|
||||
func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
|
||||
return runtime.CodecGetYAML(Codec, a.Object)
|
||||
}
|
||||
|
|
|
@ -22,10 +22,9 @@ import (
|
|||
|
||||
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
var Convert = runtime.DefaultScheme.Convert
|
||||
var Convert = newer.Scheme.Convert
|
||||
|
||||
func TestEnvConversion(t *testing.T) {
|
||||
nonCanonical := []v1beta1.EnvVar{
|
||||
|
|
|
@ -17,11 +17,15 @@ limitations under the License.
|
|||
package v1beta1
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Codec encodes internal objects to the v1beta1 scheme
|
||||
var Codec = runtime.CodecFor(api.Scheme, "v1beta1")
|
||||
|
||||
func init() {
|
||||
runtime.DefaultScheme.AddKnownTypes("v1beta1",
|
||||
api.Scheme.AddKnownTypes("v1beta1",
|
||||
&PodList{},
|
||||
&Pod{},
|
||||
&ReplicationControllerList{},
|
||||
|
|
|
@ -17,9 +17,7 @@ limitations under the License.
|
|||
package v1beta1
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
|
@ -625,13 +623,3 @@ type ServerOpList struct {
|
|||
}
|
||||
|
||||
func (*ServerOpList) IsAnAPIObject() {}
|
||||
|
||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||
type WatchEvent struct {
|
||||
// The type of the watch event; added, modified, or deleted.
|
||||
Type watch.EventType
|
||||
|
||||
// For added or modified objects, this is the new object; for deleted objects,
|
||||
// it's the state of the object immediately prior to its deletion.
|
||||
Object runtime.EmbeddedObject
|
||||
}
|
||||
|
|
|
@ -17,11 +17,67 @@ limitations under the License.
|
|||
package v1beta2
|
||||
|
||||
import (
|
||||
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
runtime.DefaultScheme.AddConversionFuncs()
|
||||
newer.Scheme.AddConversionFuncs(
|
||||
// EnvVar's Key is deprecated in favor of Name.
|
||||
func(in *newer.EnvVar, out *EnvVar, s conversion.Scope) error {
|
||||
out.Value = in.Value
|
||||
out.Key = in.Name
|
||||
out.Name = in.Name
|
||||
return nil
|
||||
},
|
||||
func(in *EnvVar, out *newer.EnvVar, s conversion.Scope) error {
|
||||
out.Value = in.Value
|
||||
if in.Name != "" {
|
||||
out.Name = in.Name
|
||||
} else {
|
||||
out.Name = in.Key
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
// Path & MountType are deprecated.
|
||||
func(in *newer.VolumeMount, out *VolumeMount, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.MountPath = in.MountPath
|
||||
out.Path = in.MountPath
|
||||
out.MountType = "" // MountType is ignored.
|
||||
return nil
|
||||
},
|
||||
func(in *VolumeMount, out *newer.VolumeMount, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.ReadOnly = in.ReadOnly
|
||||
if in.MountPath == "" {
|
||||
out.MountPath = in.Path
|
||||
} else {
|
||||
out.MountPath = in.MountPath
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
// MinionList.Items had a wrong name in v1beta1
|
||||
func(in *newer.MinionList, out *MinionList, s conversion.Scope) error {
|
||||
s.Convert(&in.JSONBase, &out.JSONBase, 0)
|
||||
s.Convert(&in.Items, &out.Items, 0)
|
||||
out.Minions = out.Items
|
||||
return nil
|
||||
},
|
||||
func(in *MinionList, out *newer.MinionList, s conversion.Scope) error {
|
||||
s.Convert(&in.JSONBase, &out.JSONBase, 0)
|
||||
if len(in.Items) == 0 {
|
||||
s.Convert(&in.Minions, &out.Items, 0)
|
||||
} else {
|
||||
s.Convert(&in.Items, &out.Items, 0)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// EmbeddedObject implements a Codec specific version of an
|
||||
|
|
|
@ -17,14 +17,15 @@ limitations under the License.
|
|||
package v1beta2
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Codec encodes runtime objects to the v1beta2 scheme
|
||||
var Codec = runtime.CodecFor(runtime.DefaultScheme, "v1beta2")
|
||||
// Codec encodes internal objects to the v1beta2 scheme
|
||||
var Codec = runtime.CodecFor(api.Scheme, "v1beta2")
|
||||
|
||||
func init() {
|
||||
runtime.DefaultScheme.AddKnownTypes("v1beta2",
|
||||
api.Scheme.AddKnownTypes("v1beta2",
|
||||
&PodList{},
|
||||
&Pod{},
|
||||
&ReplicationControllerList{},
|
||||
|
|
|
@ -17,9 +17,7 @@ limitations under the License.
|
|||
package v1beta2
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
|
@ -55,8 +53,8 @@ type ContainerManifest struct {
|
|||
// Required: This must be a DNS_SUBDOMAIN.
|
||||
// TODO: ID on Manifest is deprecated and will be removed in the future.
|
||||
ID string `yaml:"id" json:"id"`
|
||||
// TODO: UUID on Manifext is deprecated in the future once we are done
|
||||
// with the API refactory. It is required for now to determine the instance
|
||||
// TODO: UUID on Manifest is deprecated in the future once we are done
|
||||
// with the API refactoring. It is required for now to determine the instance
|
||||
// of a Pod.
|
||||
UUID string `yaml:"uuid,omitempty" json:"uuid,omitempty"`
|
||||
Volumes []Volume `yaml:"volumes" json:"volumes"`
|
||||
|
@ -166,7 +164,6 @@ type ExecAction struct {
|
|||
// command is root ('/') in the container's filesystem. The command is simply exec'd, it is
|
||||
// not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use
|
||||
// a shell, you need to explicitly call out to that shell.
|
||||
// A return code of zero is treated as 'Healthy', non-zero is 'Unhealthy'
|
||||
Command []string `yaml:"command,omitempty" json:"command,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -210,7 +207,6 @@ type Container struct {
|
|||
}
|
||||
|
||||
// Handler defines a specific action that should be taken
|
||||
// TODO: merge this with liveness probing?
|
||||
// TODO: pass structured data to these actions, and document that data here.
|
||||
type Handler struct {
|
||||
// One and only one of the following should be specified.
|
||||
|
@ -252,8 +248,6 @@ type JSONBase struct {
|
|||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
func (*JSONBase) IsAnAPIObject() {}
|
||||
|
||||
// PodStatus represents a status of a pod.
|
||||
type PodStatus string
|
||||
|
||||
|
@ -303,18 +297,19 @@ type ContainerStatus struct {
|
|||
}
|
||||
|
||||
// PodInfo contains one entry for every container with available info.
|
||||
// TODO(dchen1107): Replace docker.Container below with ContainerStatus defined above.
|
||||
type PodInfo map[string]docker.Container
|
||||
|
||||
type RestartPolicyAlways struct{}
|
||||
|
||||
// TODO(dchen1107): Define what kinds of failures should restart
|
||||
// TODO(dchen1107): Define what kinds of failures should restart.
|
||||
// TODO(dchen1107): Decide whether to support policy knobs, and, if so, which ones.
|
||||
type RestartPolicyOnFailure struct{}
|
||||
|
||||
type RestartPolicyNever struct{}
|
||||
|
||||
type RestartPolicy struct {
|
||||
// Only one of the following restart policy may be specified.
|
||||
// Only one of the following restart policies may be specified.
|
||||
// If none of the following policies is specified, the default one
|
||||
// is RestartPolicyAlways.
|
||||
Always *RestartPolicyAlways `json:"always,omitempty" yaml:"always,omitempty"`
|
||||
|
@ -333,9 +328,9 @@ type PodState struct {
|
|||
// The key of this map is the *name* of the container within the manifest; it has one
|
||||
// entry per container in the manifest. The value of this map is currently the output
|
||||
// of `docker inspect`. This output format is *not* final and should not be relied
|
||||
// upon. To allow marshalling/unmarshalling, we copied the client's structs and added
|
||||
// json/yaml tags.
|
||||
// TODO: Make real decisions about what our info should look like.
|
||||
// upon.
|
||||
// TODO: Make real decisions about what our info should look like. Re-enable fuzz test
|
||||
// when we have done this.
|
||||
Info PodInfo `json:"info,omitempty" yaml:"info,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -550,14 +545,14 @@ const (
|
|||
// resource.
|
||||
// "id" string - the identifier of the missing resource
|
||||
// Status code 404
|
||||
StatusReasonNotFound StatusReason = "notFound"
|
||||
StatusReasonNotFound StatusReason = "not_found"
|
||||
|
||||
// StatusReasonAlreadyExists means the resource you are creating already exists.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the conflicting resource
|
||||
// "id" string - the identifier of the conflicting resource
|
||||
// Status code 409
|
||||
StatusReasonAlreadyExists StatusReason = "alreadyExists"
|
||||
StatusReasonAlreadyExists StatusReason = "already_exists"
|
||||
|
||||
// StatusReasonConflict means the requested update operation cannot be completed
|
||||
// due to a conflict in the operation. The client may need to alter the request.
|
||||
|
@ -565,6 +560,19 @@ const (
|
|||
// conflict.
|
||||
// Status code 409
|
||||
StatusReasonConflict StatusReason = "conflict"
|
||||
|
||||
// StatusReasonInvalid means the requested create or update operation cannot be
|
||||
// completed due to invalid data provided as part of the request. The client may
|
||||
// need to alter the request. When set, the client may use the StatusDetails
|
||||
// message field as a summary of the issues encountered.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the invalid resource
|
||||
// "id" string - the identifier of the invalid resource
|
||||
// "causes" - one or more StatusCause entries indicating the data in the
|
||||
// provided resource that was invalid. The code, message, and
|
||||
// field attributes will be set.
|
||||
// Status code 422
|
||||
StatusReasonInvalid StatusReason = "invalid"
|
||||
)
|
||||
|
||||
// StatusCause provides more information about an api.Status failure, including
|
||||
|
@ -625,13 +633,3 @@ type ServerOpList struct {
|
|||
}
|
||||
|
||||
func (*ServerOpList) IsAnAPIObject() {}
|
||||
|
||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||
type WatchEvent struct {
|
||||
// The type of the watch event; added, modified, or deleted.
|
||||
Type watch.EventType
|
||||
|
||||
// For added or modified objects, this is the new object; for deleted objects,
|
||||
// it's the state of the object immediately prior to its deletion.
|
||||
Object runtime.EmbeddedObject
|
||||
}
|
||||
|
|
|
@ -14,12 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
package v1beta3
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
|
@ -55,8 +53,8 @@ type ContainerManifest struct {
|
|||
// Required: This must be a DNS_SUBDOMAIN.
|
||||
// TODO: ID on Manifest is deprecated and will be removed in the future.
|
||||
ID string `yaml:"id" json:"id"`
|
||||
// TODO: UUID on Manifext is deprecated in the future once we are done
|
||||
// with the API refactory. It is required for now to determine the instance
|
||||
// TODO: UUID on Manifest is deprecated in the future once we are done
|
||||
// with the API refactoring. It is required for now to determine the instance
|
||||
// of a Pod.
|
||||
UUID string `yaml:"uuid,omitempty" json:"uuid,omitempty"`
|
||||
Volumes []Volume `yaml:"volumes" json:"volumes"`
|
||||
|
@ -124,22 +122,13 @@ type VolumeMount struct {
|
|||
// Optional: Defaults to false (read-write).
|
||||
ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
|
||||
// Required.
|
||||
// Exactly one of the following must be set. If both are set, prefer MountPath.
|
||||
// DEPRECATED: Path will be removed in a future version of the API.
|
||||
MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"`
|
||||
Path string `yaml:"path,omitempty" json:"path,omitempty"`
|
||||
// One of: "LOCAL" (local volume) or "HOST" (external mount from the host). Default: LOCAL.
|
||||
// DEPRECATED: MountType will be removed in a future version of the API.
|
||||
MountType string `yaml:"mountType,omitempty" json:"mountType,omitempty"`
|
||||
}
|
||||
|
||||
// EnvVar represents an environment variable present in a Container.
|
||||
type EnvVar struct {
|
||||
// Required: This must be a C_IDENTIFIER.
|
||||
// Exactly one of the following must be set. If both are set, prefer Name.
|
||||
// DEPRECATED: EnvVar.Key will be removed in a future version of the API.
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Key string `yaml:"key,omitempty" json:"key,omitempty"`
|
||||
// Optional: defaults to "".
|
||||
Value string `yaml:"value,omitempty" json:"value,omitempty"`
|
||||
}
|
||||
|
@ -166,7 +155,6 @@ type ExecAction struct {
|
|||
// command is root ('/') in the container's filesystem. The command is simply exec'd, it is
|
||||
// not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use
|
||||
// a shell, you need to explicitly call out to that shell.
|
||||
// A return code of zero is treated as 'Healthy', non-zero is 'Unhealthy'
|
||||
Command []string `yaml:"command,omitempty" json:"command,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -210,7 +198,6 @@ type Container struct {
|
|||
}
|
||||
|
||||
// Handler defines a specific action that should be taken
|
||||
// TODO: merge this with liveness probing?
|
||||
// TODO: pass structured data to these actions, and document that data here.
|
||||
type Handler struct {
|
||||
// One and only one of the following should be specified.
|
||||
|
@ -252,8 +239,6 @@ type JSONBase struct {
|
|||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
func (*JSONBase) IsAnAPIObject() {}
|
||||
|
||||
// PodStatus represents a status of a pod.
|
||||
type PodStatus string
|
||||
|
||||
|
@ -303,18 +288,19 @@ type ContainerStatus struct {
|
|||
}
|
||||
|
||||
// PodInfo contains one entry for every container with available info.
|
||||
// TODO(dchen1107): Replace docker.Container below with ContainerStatus defined above.
|
||||
type PodInfo map[string]docker.Container
|
||||
|
||||
type RestartPolicyAlways struct{}
|
||||
|
||||
// TODO(dchen1107): Define what kinds of failures should restart
|
||||
// TODO(dchen1107): Define what kinds of failures should restart.
|
||||
// TODO(dchen1107): Decide whether to support policy knobs, and, if so, which ones.
|
||||
type RestartPolicyOnFailure struct{}
|
||||
|
||||
type RestartPolicyNever struct{}
|
||||
|
||||
type RestartPolicy struct {
|
||||
// Only one of the following restart policy may be specified.
|
||||
// Only one of the following restart policies may be specified.
|
||||
// If none of the following policies is specified, the default one
|
||||
// is RestartPolicyAlways.
|
||||
Always *RestartPolicyAlways `json:"always,omitempty" yaml:"always,omitempty"`
|
||||
|
@ -333,9 +319,9 @@ type PodState struct {
|
|||
// The key of this map is the *name* of the container within the manifest; it has one
|
||||
// entry per container in the manifest. The value of this map is currently the output
|
||||
// of `docker inspect`. This output format is *not* final and should not be relied
|
||||
// upon. To allow marshalling/unmarshalling, we copied the client's structs and added
|
||||
// json/yaml tags.
|
||||
// TODO: Make real decisions about what our info should look like.
|
||||
// upon.
|
||||
// TODO: Make real decisions about what our info should look like. Re-enable fuzz test
|
||||
// when we have done this.
|
||||
Info PodInfo `json:"info,omitempty" yaml:"info,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -451,9 +437,6 @@ func (*Minion) IsAnAPIObject() {}
|
|||
// MinionList is a list of minions.
|
||||
type MinionList struct {
|
||||
JSONBase `json:",inline" yaml:",inline"`
|
||||
// DEPRECATED: the below Minions is due to a naming mistake and
|
||||
// will be replaced with Items in the future.
|
||||
Minions []Minion `json:"minions,omitempty" yaml:"minions,omitempty"`
|
||||
Items []Minion `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -550,14 +533,14 @@ const (
|
|||
// resource.
|
||||
// "id" string - the identifier of the missing resource
|
||||
// Status code 404
|
||||
StatusReasonNotFound StatusReason = "notFound"
|
||||
StatusReasonNotFound StatusReason = "not_found"
|
||||
|
||||
// StatusReasonAlreadyExists means the resource you are creating already exists.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the conflicting resource
|
||||
// "id" string - the identifier of the conflicting resource
|
||||
// Status code 409
|
||||
StatusReasonAlreadyExists StatusReason = "alreadyExists"
|
||||
StatusReasonAlreadyExists StatusReason = "already_exists"
|
||||
|
||||
// StatusReasonConflict means the requested update operation cannot be completed
|
||||
// due to a conflict in the operation. The client may need to alter the request.
|
||||
|
@ -565,6 +548,19 @@ const (
|
|||
// conflict.
|
||||
// Status code 409
|
||||
StatusReasonConflict StatusReason = "conflict"
|
||||
|
||||
// StatusReasonInvalid means the requested create or update operation cannot be
|
||||
// completed due to invalid data provided as part of the request. The client may
|
||||
// need to alter the request. When set, the client may use the StatusDetails
|
||||
// message field as a summary of the issues encountered.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the invalid resource
|
||||
// "id" string - the identifier of the invalid resource
|
||||
// "causes" - one or more StatusCause entries indicating the data in the
|
||||
// provided resource that was invalid. The code, message, and
|
||||
// field attributes will be set.
|
||||
// Status code 422
|
||||
StatusReasonInvalid StatusReason = "invalid"
|
||||
)
|
||||
|
||||
// StatusCause provides more information about an api.Status failure, including
|
||||
|
@ -625,13 +621,3 @@ type ServerOpList struct {
|
|||
}
|
||||
|
||||
func (*ServerOpList) IsAnAPIObject() {}
|
||||
|
||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||
type WatchEvent struct {
|
||||
// The type of the watch event; added, modified, or deleted.
|
||||
Type watch.EventType
|
||||
|
||||
// For added or modified objects, this is the new object; for deleted objects,
|
||||
// it's the state of the object immediately prior to its deletion.
|
||||
Object runtime.EmbeddedObject
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||
// These are not API objects and are unversioned today.
|
||||
type WatchEvent struct {
|
||||
// The type of the watch event; added, modified, or deleted.
|
||||
Type watch.EventType
|
||||
|
||||
// For added or modified objects, this is the new object; for deleted objects,
|
||||
// it's the state of the object immediately prior to its deletion.
|
||||
Object EmbeddedObject
|
||||
}
|
||||
|
||||
// watchSerialization defines the JSON wire equivalent of watch.Event
|
||||
type watchSerialization struct {
|
||||
Type watch.EventType
|
||||
Object json.RawMessage
|
||||
}
|
||||
|
||||
// NewJSONWatcHEvent returns an object that will serialize to JSON and back
|
||||
// to a WatchEvent.
|
||||
func NewJSONWatchEvent(codec runtime.Codec, event watch.Event) (interface{}, error) {
|
||||
obj, ok := event.Object.(runtime.Object)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("The event object cannot be safely converted to JSON: %v", reflect.TypeOf(event.Object).Name())
|
||||
}
|
||||
data, err := codec.Encode(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &watchSerialization{event.Type, json.RawMessage(data)}, nil
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEmbeddedDefaultSerialization(t *testing.T) {
|
||||
expected := WatchEvent{
|
||||
Type: "foo",
|
||||
Object: EmbeddedObject{&Pod{}},
|
||||
}
|
||||
data, err := json.Marshal(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := WatchEvent{}
|
||||
if err := json.Unmarshal(data, &actual); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Expected %#v, Got %#v", expected, actual)
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import (
|
|||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
|
@ -46,8 +47,8 @@ func convert(obj runtime.Object) (runtime.Object, error) {
|
|||
var codec = latest.Codec
|
||||
|
||||
func init() {
|
||||
latest.Codec.AddKnownTypes("", &Simple{}, &SimpleList{})
|
||||
latest.Codec.AddKnownTypes("v1beta1", &Simple{}, &SimpleList{})
|
||||
api.Scheme.AddKnownTypes("", &Simple{}, &SimpleList{})
|
||||
api.Scheme.AddKnownTypes(latest.Version, &Simple{}, &SimpleList{})
|
||||
}
|
||||
|
||||
type Simple struct {
|
||||
|
@ -95,7 +96,7 @@ func (storage *SimpleRESTStorage) List(labels.Selector) (runtime.Object, error)
|
|||
}
|
||||
|
||||
func (storage *SimpleRESTStorage) Get(id string) (runtime.Object, error) {
|
||||
return latest.Codec.CopyOrDie(&storage.item), storage.errors["get"]
|
||||
return api.Scheme.CopyOrDie(&storage.item), storage.errors["get"]
|
||||
}
|
||||
|
||||
func (storage *SimpleRESTStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||
|
|
|
@ -74,7 +74,7 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
// TODO: This is one watch per connection. We want to multiplex, so that
|
||||
// multiple watches of the same thing don't create two watches downstream.
|
||||
watchServer := &WatchServer{watching}
|
||||
watchServer := &WatchServer{watching, h.codec}
|
||||
if req.Header.Get("Connection") == "Upgrade" && req.Header.Get("Upgrade") == "websocket" {
|
||||
websocket.Handler(watchServer.HandleWS).ServeHTTP(httplog.Unlogged(w), req)
|
||||
} else {
|
||||
|
@ -89,6 +89,7 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
|
||||
type WatchServer struct {
|
||||
watching watch.Interface
|
||||
codec runtime.Codec
|
||||
}
|
||||
|
||||
// HandleWS implements a websocket handler.
|
||||
|
@ -111,15 +112,17 @@ func (w *WatchServer) HandleWS(ws *websocket.Conn) {
|
|||
// End of results.
|
||||
return
|
||||
}
|
||||
err := websocket.JSON.Send(ws, &api.WatchEvent{
|
||||
Type: event.Type,
|
||||
Object: runtime.EmbeddedObject{event.Object},
|
||||
})
|
||||
obj, err := api.NewJSONWatchEvent(w.codec, event)
|
||||
if err != nil {
|
||||
// Client disconnect.
|
||||
w.watching.Stop()
|
||||
return
|
||||
}
|
||||
if err := websocket.JSON.Send(ws, obj); err != nil {
|
||||
// Client disconnect.
|
||||
w.watching.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,15 +161,17 @@ func (self *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// End of results.
|
||||
return
|
||||
}
|
||||
err := encoder.Encode(&api.WatchEvent{
|
||||
Type: event.Type,
|
||||
Object: runtime.EmbeddedObject{event.Object},
|
||||
})
|
||||
obj, err := api.NewJSONWatchEvent(self.codec, event)
|
||||
if err != nil {
|
||||
// Client disconnect.
|
||||
self.watching.Stop()
|
||||
return
|
||||
}
|
||||
if err := encoder.Encode(obj); err != nil {
|
||||
// Client disconnect.
|
||||
self.watching.Stop()
|
||||
return
|
||||
}
|
||||
flusher.Flush()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,26 +114,22 @@ func TestWatchHTTP(t *testing.T) {
|
|||
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
|
||||
try := func(action watch.EventType, object runtime.Object) {
|
||||
for i, item := range watchTestTable {
|
||||
// Send
|
||||
simpleStorage.fakeWatch.Action(action, object)
|
||||
simpleStorage.fakeWatch.Action(item.t, item.obj)
|
||||
// Test receive
|
||||
var got api.WatchEvent
|
||||
err := decoder.Decode(&got)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
t.Fatalf("%d: Unexpected error: %v", i, err)
|
||||
}
|
||||
if got.Type != action {
|
||||
t.Errorf("Unexpected type: %v", got.Type)
|
||||
if got.Type != item.t {
|
||||
t.Errorf("%d: Unexpected type: %v", i, got.Type)
|
||||
}
|
||||
if e, a := object, got.Object.Object; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
if e, a := item.obj, got.Object.Object; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d: Expected %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range watchTestTable {
|
||||
try(item.t, item.obj)
|
||||
}
|
||||
simpleStorage.fakeWatch.Stop()
|
||||
|
||||
var got api.WatchEvent
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
|
|
|
@ -19,7 +19,6 @@ package client
|
|||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
@ -44,7 +43,7 @@ type Fake struct {
|
|||
|
||||
func (c *Fake) ListPods(selector labels.Selector) (*api.PodList, error) {
|
||||
c.Actions = append(c.Actions, FakeAction{Action: "list-pods"})
|
||||
return runtime.DefaultScheme.CopyOrDie(&c.Pods).(*api.PodList), nil
|
||||
return api.Scheme.CopyOrDie(&c.Pods).(*api.PodList), nil
|
||||
}
|
||||
|
||||
func (c *Fake) GetPod(name string) (*api.Pod, error) {
|
||||
|
@ -74,7 +73,7 @@ func (c *Fake) ListReplicationControllers(selector labels.Selector) (*api.Replic
|
|||
|
||||
func (c *Fake) GetReplicationController(name string) (*api.ReplicationController, error) {
|
||||
c.Actions = append(c.Actions, FakeAction{Action: "get-controller", Value: name})
|
||||
return runtime.DefaultScheme.CopyOrDie(&c.Ctrl).(*api.ReplicationController), nil
|
||||
return api.Scheme.CopyOrDie(&c.Ctrl).(*api.ReplicationController), nil
|
||||
}
|
||||
|
||||
func (c *Fake) CreateReplicationController(controller *api.ReplicationController) (*api.ReplicationController, error) {
|
||||
|
@ -129,7 +128,7 @@ func (c *Fake) WatchServices(label, field labels.Selector, resourceVersion uint6
|
|||
|
||||
func (c *Fake) ListEndpoints(selector labels.Selector) (*api.EndpointsList, error) {
|
||||
c.Actions = append(c.Actions, FakeAction{Action: "list-endpoints"})
|
||||
return runtime.DefaultScheme.CopyOrDie(&c.EndpointsList).(*api.EndpointsList), c.Err
|
||||
return api.Scheme.CopyOrDie(&c.EndpointsList).(*api.EndpointsList), c.Err
|
||||
}
|
||||
|
||||
func (c *Fake) WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
|
||||
|
|
|
@ -28,9 +28,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
cwatch "github.com/GoogleCloudPlatform/kubernetes/pkg/client/watch"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/golang/glog"
|
||||
|
@ -269,7 +269,7 @@ func (r *Request) Watch() (watch.Interface, error) {
|
|||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("Got status: %v", response.StatusCode)
|
||||
}
|
||||
return watch.NewStreamWatcher(tools.NewAPIEventDecoder(response.Body)), nil
|
||||
return watch.NewStreamWatcher(cwatch.NewAPIEventDecoder(response.Body)), nil
|
||||
}
|
||||
|
||||
// Do formats and executes the request. Returns the API object received, or an error.
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
|
@ -401,7 +402,13 @@ func TestWatch(t *testing.T) {
|
|||
|
||||
encoder := json.NewEncoder(w)
|
||||
for _, item := range table {
|
||||
encoder.Encode(&api.WatchEvent{item.t, runtime.EmbeddedObject{item.obj}})
|
||||
data, err := api.NewJSONWatchEvent(latest.Codec, watch.Event{item.t, item.obj})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := encoder.Encode(data); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
flusher.Flush()
|
||||
}
|
||||
}))
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tools
|
||||
package watch
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -28,6 +28,8 @@ import (
|
|||
|
||||
// APIEventDecoder implements the watch.Decoder interface for io.ReadClosers that
|
||||
// have contents which consist of a series of api.WatchEvent objects encoded via JSON.
|
||||
// It will decode any object which is registered to convert to api.WatchEvent via
|
||||
// api.Scheme
|
||||
type APIEventDecoder struct {
|
||||
stream io.ReadCloser
|
||||
decoder *json.Decoder
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tools
|
||||
package watch
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -24,29 +24,37 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
type watchSerialization struct {
|
||||
Type watch.EventType
|
||||
Object json.RawMessage
|
||||
}
|
||||
|
||||
func TestDecoder(t *testing.T) {
|
||||
out, in := io.Pipe()
|
||||
encoder := json.NewEncoder(in)
|
||||
decoder := NewAPIEventDecoder(out)
|
||||
|
||||
expect := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
encoder := json.NewEncoder(in)
|
||||
go func() {
|
||||
err := encoder.Encode(api.WatchEvent{watch.Added, runtime.EmbeddedObject{expect}})
|
||||
data, err := v1beta1.Codec.Encode(expect)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
if err := encoder.Encode(&watchSerialization{watch.Added, json.RawMessage(data)}); err != nil {
|
||||
t.Errorf("Unexpected error %v", err)
|
||||
}
|
||||
in.Close()
|
||||
}()
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
action, got, err := decoder.Decode()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %v", err)
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
if e, a := watch.Added, action; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
|
@ -54,17 +62,12 @@ func TestDecoder(t *testing.T) {
|
|||
if e, a := expect, got; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
t.Logf("Exited read")
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
break
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Error("Timeout")
|
||||
}
|
||||
<-done
|
||||
|
||||
done = make(chan struct{})
|
||||
|
||||
go func() {
|
||||
_, _, err := decoder.Decode()
|
||||
if err == nil {
|
||||
|
@ -72,15 +75,9 @@ func TestDecoder(t *testing.T) {
|
|||
}
|
||||
close(done)
|
||||
}()
|
||||
<-done
|
||||
|
||||
decoder.Close()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
break
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Error("Timeout")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder_SourceClose(t *testing.T) {
|
|
@ -27,6 +27,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
|
@ -169,7 +171,7 @@ func TestSyncReplicationControllerCreates(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateReplica(t *testing.T) {
|
||||
body, _ := latest.Codec.Encode(&api.Pod{})
|
||||
body, _ := v1beta1.Codec.Encode(&api.Pod{})
|
||||
fakeHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
ResponseBody: string(body),
|
||||
|
@ -209,7 +211,7 @@ func TestCreateReplica(t *testing.T) {
|
|||
expectedPod := api.Pod{
|
||||
JSONBase: api.JSONBase{
|
||||
Kind: "Pod",
|
||||
APIVersion: "v1beta1",
|
||||
APIVersion: latest.Version,
|
||||
},
|
||||
Labels: controllerSpec.DesiredState.PodTemplate.Labels,
|
||||
DesiredState: controllerSpec.DesiredState.PodTemplate.DesiredState,
|
||||
|
@ -287,12 +289,12 @@ func TestSyncronize(t *testing.T) {
|
|||
|
||||
fakePodHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
ResponseBody: "{\"apiVersion\": \"v1beta1\", \"kind\": \"PodList\"}",
|
||||
ResponseBody: "{\"apiVersion\": \"" + latest.Version + "\", \"kind\": \"PodList\"}",
|
||||
T: t,
|
||||
}
|
||||
fakeControllerHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
ResponseBody: latest.Codec.EncodeOrDie(&api.ReplicationControllerList{
|
||||
ResponseBody: runtime.EncodeOrDie(latest.Codec, &api.ReplicationControllerList{
|
||||
Items: []api.ReplicationController{
|
||||
controllerSpec1,
|
||||
controllerSpec2,
|
||||
|
|
|
@ -25,14 +25,14 @@ import (
|
|||
// Decode converts a YAML or JSON string back into a pointer to an api object.
|
||||
// Deduces the type based upon the fields added by the MetaInsertionFactory
|
||||
// technique. The object will be converted, if necessary, into the
|
||||
// s.InternalVersion type before being returned. Decode will refuse to decode
|
||||
// objects without a version, because that's probably an error.
|
||||
// s.InternalVersion type before being returned. Decode will not decode
|
||||
// objects without version set unless InternalVersion is also "".
|
||||
func (s *Scheme) Decode(data []byte) (interface{}, error) {
|
||||
version, kind, err := s.DataVersionAndKind(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if version == "" {
|
||||
if version == "" && s.InternalVersion != "" {
|
||||
return nil, fmt.Errorf("version not set in '%s'", string(data))
|
||||
}
|
||||
obj, err := s.NewObject(version, kind)
|
||||
|
|
|
@ -21,16 +21,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
|
||||
func (s *Scheme) EncodeOrDie(obj interface{}) string {
|
||||
bytes, err := s.Encode(obj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
// Encode turns the given api object into an appropriate JSON string.
|
||||
// EncodeToVersion turns the given api object into an appropriate JSON string.
|
||||
// Obj may be a pointer to a struct, or a struct. If a struct, a copy
|
||||
// will be made, therefore it's recommended to pass a pointer to a
|
||||
// struct. The type must have been registered.
|
||||
|
@ -58,11 +49,6 @@ func (s *Scheme) EncodeOrDie(obj interface{}) string {
|
|||
// objects, whether they be in our storage layer (e.g., etcd), or in user's
|
||||
// config files.
|
||||
//
|
||||
func (s *Scheme) Encode(obj interface{}) (data []byte, err error) {
|
||||
return s.EncodeToVersion(obj, s.ExternalVersion)
|
||||
}
|
||||
|
||||
// EncodeToVersion is like Encode, but you may choose the version.
|
||||
func (s *Scheme) EncodeToVersion(obj interface{}, destVersion string) (data []byte, err error) {
|
||||
obj = maybeCopy(obj)
|
||||
v, _ := enforcePtr(obj) // maybeCopy guarantees a pointer
|
||||
|
|
|
@ -66,9 +66,6 @@ type Scheme struct {
|
|||
// you use "" for the internal version.
|
||||
InternalVersion string
|
||||
|
||||
// ExternalVersion is the default external version.
|
||||
ExternalVersion string
|
||||
|
||||
// MetaInsertionFactory is used to create an object to store and retrieve
|
||||
// the version and kind information for all objects. The default uses the
|
||||
// keys "version" and "kind" respectively.
|
||||
|
@ -83,7 +80,6 @@ func NewScheme() *Scheme {
|
|||
typeToKind: map[reflect.Type]string{},
|
||||
converter: NewConverter(),
|
||||
InternalVersion: "",
|
||||
ExternalVersion: "v1",
|
||||
MetaInsertionFactory: metaInsertion{},
|
||||
}
|
||||
s.converter.NameFunc = s.nameFunc
|
||||
|
@ -146,6 +142,19 @@ func (s *Scheme) AddKnownTypeWithName(version, kind string, obj interface{}) {
|
|||
s.typeToKind[t] = kind
|
||||
}
|
||||
|
||||
// KnownTypes returns an array of the types that are known for a particular version.
|
||||
func (s *Scheme) KnownTypes(version string) map[string]reflect.Type {
|
||||
all, ok := s.versionMap[version]
|
||||
if !ok {
|
||||
return map[string]reflect.Type{}
|
||||
}
|
||||
types := make(map[string]reflect.Type)
|
||||
for k, v := range all {
|
||||
types[k] = v
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
// NewObject returns a new object of the given version and name,
|
||||
// or an error if it hasn't been registered.
|
||||
func (s *Scheme) NewObject(versionName, typeName string) (interface{}, error) {
|
||||
|
|
|
@ -125,7 +125,6 @@ func GetTestScheme() *Scheme {
|
|||
s.AddKnownTypes("v1", &ExternalInternalSame{})
|
||||
s.AddKnownTypeWithName("v1", "TestType1", &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName("v1", "TestType2", &ExternalTestType2{})
|
||||
s.ExternalVersion = "v1"
|
||||
s.InternalVersion = ""
|
||||
s.MetaInsertionFactory = testMetaInsertionFactory{}
|
||||
return s
|
||||
|
@ -178,7 +177,7 @@ func runTest(t *testing.T, source interface{}) {
|
|||
TestObjectFuzzer.Fuzz(source)
|
||||
|
||||
s := GetTestScheme()
|
||||
data, err := s.Encode(source)
|
||||
data, err := s.EncodeToVersion(source, "v1")
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v (%#v)", name, err, source)
|
||||
return
|
||||
|
@ -221,7 +220,7 @@ func TestEncode_NonPtr(t *testing.T) {
|
|||
s := GetTestScheme()
|
||||
tt := TestType1{A: "I'm not a pointer object"}
|
||||
obj := interface{}(tt)
|
||||
data, err := s.Encode(obj)
|
||||
data, err := s.EncodeToVersion(obj, "v1")
|
||||
obj2, err2 := s.Decode(data)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||
|
@ -238,7 +237,7 @@ func TestEncode_Ptr(t *testing.T) {
|
|||
s := GetTestScheme()
|
||||
tt := &TestType1{A: "I am a pointer object"}
|
||||
obj := interface{}(tt)
|
||||
data, err := s.Encode(obj)
|
||||
data, err := s.EncodeToVersion(obj, "v1")
|
||||
obj2, err2 := s.Decode(data)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||
|
@ -255,7 +254,6 @@ func TestBadJSONRejection(t *testing.T) {
|
|||
s := GetTestScheme()
|
||||
badJSONs := [][]byte{
|
||||
[]byte(`{"myVersionKey":"v1"}`), // Missing kind
|
||||
[]byte(`{"myKindKey":"TestType1"}`), // Missing version
|
||||
[]byte(`{"myVersionKey":"v1","myKindKey":"bar"}`), // Unknown kind
|
||||
[]byte(`{"myVersionKey":"bar","myKindKey":"TestType1"}`), // Unknown version
|
||||
}
|
||||
|
@ -270,6 +268,23 @@ func TestBadJSONRejection(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBadJSONRejectionForSetInternalVersion(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
s.InternalVersion = "v1"
|
||||
badJSONs := [][]byte{
|
||||
[]byte(`{"myKindKey":"TestType1"}`), // Missing version
|
||||
}
|
||||
for _, b := range badJSONs {
|
||||
if _, err := s.Decode(b); err == nil {
|
||||
t.Errorf("Did not reject bad json: %s", string(b))
|
||||
}
|
||||
}
|
||||
badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`)
|
||||
if err := s.DecodeInto(badJSONKindMismatch, &TestType1{}); err == nil {
|
||||
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetaValues(t *testing.T) {
|
||||
type InternalSimple struct {
|
||||
Version string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
|
@ -283,7 +298,6 @@ func TestMetaValues(t *testing.T) {
|
|||
}
|
||||
s := NewScheme()
|
||||
s.InternalVersion = ""
|
||||
s.ExternalVersion = "externalVersion"
|
||||
s.AddKnownTypeWithName("", "Simple", &InternalSimple{})
|
||||
s.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
|
||||
|
||||
|
@ -373,7 +387,6 @@ func TestMetaValuesUnregisteredConvert(t *testing.T) {
|
|||
}
|
||||
s := NewScheme()
|
||||
s.InternalVersion = ""
|
||||
s.ExternalVersion = "externalVersion"
|
||||
// We deliberately don't register the types.
|
||||
|
||||
internalToExternalCalls := 0
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func validateAction(expectedAction, actualAction client.FakeAction, t *testing.T) {
|
||||
|
@ -94,7 +93,7 @@ func TestUpdateWithNewImage(t *testing.T) {
|
|||
}
|
||||
validateAction(client.FakeAction{Action: "get-controller", Value: "foo"}, fakeClient.Actions[0], t)
|
||||
|
||||
newCtrl := runtime.DefaultScheme.CopyOrDie(&fakeClient.Ctrl).(*api.ReplicationController)
|
||||
newCtrl := api.Scheme.CopyOrDie(&fakeClient.Ctrl).(*api.ReplicationController)
|
||||
newCtrl.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image = "fooImage:2"
|
||||
validateAction(client.FakeAction{Action: "update-controller", Value: newCtrl}, fakeClient.Actions[1], t)
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"gopkg.in/v1/yaml"
|
||||
)
|
||||
|
@ -125,8 +127,9 @@ type TestParseType struct {
|
|||
func (*TestParseType) IsAnAPIObject() {}
|
||||
|
||||
func TestParseCustomType(t *testing.T) {
|
||||
latest.Codec.AddKnownTypes("", &TestParseType{})
|
||||
latest.Codec.AddKnownTypes("v1beta1", &TestParseType{})
|
||||
api.Scheme.AddKnownTypes("", &TestParseType{})
|
||||
api.Scheme.AddKnownTypes("v1beta1", &TestParseType{})
|
||||
api.Scheme.AddKnownTypes("v1beta2", &TestParseType{})
|
||||
parser := NewParser(map[string]runtime.Object{
|
||||
"custom": &TestParseType{},
|
||||
})
|
||||
|
|
|
@ -21,8 +21,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// ProxyServer is a http.Handler which proxies Kubernetes APIs to remote API server.
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/golang/glog"
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"gopkg.in/v1/yaml"
|
||||
)
|
||||
|
||||
|
|
|
@ -24,9 +24,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
|
@ -48,7 +47,7 @@ func NewSourceEtcd(key string, client tools.EtcdClient, updates chan<- interface
|
|||
helper := tools.EtcdHelper{
|
||||
client,
|
||||
latest.Codec,
|
||||
runtime.DefaultResourceVersioner,
|
||||
latest.ResourceVersioner,
|
||||
}
|
||||
source := &SourceEtcd{
|
||||
key: key,
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
||||
|
@ -136,5 +136,5 @@ func (m *Master) API_v1beta1() (map[string]apiserver.RESTStorage, runtime.Codec)
|
|||
for k, v := range m.storage {
|
||||
storage[k] = v
|
||||
}
|
||||
return storage, runtime.DefaultCodec
|
||||
return storage, v1beta1.Codec
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
|
|
|
@ -23,9 +23,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestNewREST(t *testing.T) {
|
||||
|
|
|
@ -26,10 +26,10 @@ import (
|
|||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestListControllersError(t *testing.T) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/constraint"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
|
@ -46,7 +47,7 @@ func NewRegistry(client tools.EtcdClient) *Registry {
|
|||
EtcdHelper: tools.EtcdHelper{
|
||||
client,
|
||||
latest.Codec,
|
||||
runtime.DefaultResourceVersioner,
|
||||
latest.ResourceVersioner,
|
||||
},
|
||||
}
|
||||
registry.manifestFactory = &BasicManifestFactory{
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
|
@ -41,7 +41,7 @@ func NewTestEtcdRegistry(client tools.EtcdClient) *Registry {
|
|||
|
||||
func TestEtcdGetPod(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.Set("/registry/pods/foo", latest.Codec.EncodeOrDie(&api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
fakeClient.Set("/registry/pods/foo", runtime.EncodeOrDie(latest.Codec, &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
pod, err := registry.GetPod("foo")
|
||||
if err != nil {
|
||||
|
@ -77,7 +77,7 @@ func TestEtcdCreatePod(t *testing.T) {
|
|||
},
|
||||
E: tools.EtcdErrorNotFound,
|
||||
}
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", latest.Codec.EncodeOrDie(&api.ContainerManifestList{}), 0)
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
err := registry.CreatePod(&api.Pod{
|
||||
JSONBase: api.JSONBase{
|
||||
|
@ -133,7 +133,7 @@ func TestEtcdCreatePodAlreadyExisting(t *testing.T) {
|
|||
fakeClient.Data["/registry/pods/foo"] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Pod{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||
},
|
||||
},
|
||||
E: nil,
|
||||
|
@ -264,7 +264,7 @@ func TestEtcdCreatePodWithExistingContainers(t *testing.T) {
|
|||
},
|
||||
E: tools.EtcdErrorNotFound,
|
||||
}
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", latest.Codec.EncodeOrDie(&api.ContainerManifestList{
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{
|
||||
Items: []api.ContainerManifest{
|
||||
{ID: "bar"},
|
||||
},
|
||||
|
@ -325,11 +325,11 @@ func TestEtcdDeletePod(t *testing.T) {
|
|||
fakeClient.TestIndex = true
|
||||
|
||||
key := "/registry/pods/foo"
|
||||
fakeClient.Set(key, latest.Codec.EncodeOrDie(&api.Pod{
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
|
||||
JSONBase: api.JSONBase{ID: "foo"},
|
||||
DesiredState: api.PodState{Host: "machine"},
|
||||
}), 0)
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", latest.Codec.EncodeOrDie(&api.ContainerManifestList{
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{
|
||||
Items: []api.ContainerManifest{
|
||||
{ID: "foo"},
|
||||
},
|
||||
|
@ -361,11 +361,11 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) {
|
|||
fakeClient.TestIndex = true
|
||||
|
||||
key := "/registry/pods/foo"
|
||||
fakeClient.Set(key, latest.Codec.EncodeOrDie(&api.Pod{
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
|
||||
JSONBase: api.JSONBase{ID: "foo"},
|
||||
DesiredState: api.PodState{Host: "machine"},
|
||||
}), 0)
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", latest.Codec.EncodeOrDie(&api.ContainerManifestList{
|
||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{
|
||||
Items: []api.ContainerManifest{
|
||||
{ID: "foo"},
|
||||
{ID: "bar"},
|
||||
|
@ -445,13 +445,13 @@ func TestEtcdListPods(t *testing.T) {
|
|||
Node: &etcd.Node{
|
||||
Nodes: []*etcd.Node{
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Pod{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
|
||||
JSONBase: api.JSONBase{ID: "foo"},
|
||||
DesiredState: api.PodState{Host: "machine"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Pod{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
|
||||
JSONBase: api.JSONBase{ID: "bar"},
|
||||
DesiredState: api.PodState{Host: "machine"},
|
||||
}),
|
||||
|
@ -520,10 +520,10 @@ func TestEtcdListControllers(t *testing.T) {
|
|||
Node: &etcd.Node{
|
||||
Nodes: []*etcd.Node{
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||
},
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -543,7 +543,7 @@ func TestEtcdListControllers(t *testing.T) {
|
|||
|
||||
func TestEtcdGetController(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.Set("/registry/controllers/foo", latest.Codec.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
fakeClient.Set("/registry/controllers/foo", runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
ctrl, err := registry.GetController("foo")
|
||||
if err != nil {
|
||||
|
@ -619,7 +619,7 @@ func TestEtcdCreateController(t *testing.T) {
|
|||
|
||||
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.Set("/registry/controllers/foo", latest.Codec.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
fakeClient.Set("/registry/controllers/foo", runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
err := registry.CreateController(&api.ReplicationController{
|
||||
|
@ -636,7 +636,7 @@ func TestEtcdUpdateController(t *testing.T) {
|
|||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.TestIndex = true
|
||||
|
||||
resp, _ := fakeClient.Set("/registry/controllers/foo", latest.Codec.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
resp, _ := fakeClient.Set("/registry/controllers/foo", runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
err := registry.UpdateController(&api.ReplicationController{
|
||||
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex},
|
||||
|
@ -662,10 +662,10 @@ func TestEtcdListServices(t *testing.T) {
|
|||
Node: &etcd.Node{
|
||||
Nodes: []*etcd.Node{
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Service{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||
},
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Service{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -711,7 +711,7 @@ func TestEtcdCreateService(t *testing.T) {
|
|||
|
||||
func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.Set("/registry/services/specs/foo", latest.Codec.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
fakeClient.Set("/registry/services/specs/foo", runtime.EncodeOrDie(latest.Codec, &api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
err := registry.CreateService(&api.Service{
|
||||
JSONBase: api.JSONBase{ID: "foo"},
|
||||
|
@ -723,7 +723,7 @@ func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
|
|||
|
||||
func TestEtcdGetService(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.Set("/registry/services/specs/foo", latest.Codec.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
fakeClient.Set("/registry/services/specs/foo", runtime.EncodeOrDie(latest.Codec, &api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
service, err := registry.GetService("foo")
|
||||
if err != nil {
|
||||
|
@ -775,7 +775,7 @@ func TestEtcdUpdateService(t *testing.T) {
|
|||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.TestIndex = true
|
||||
|
||||
resp, _ := fakeClient.Set("/registry/services/specs/foo", latest.Codec.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
resp, _ := fakeClient.Set("/registry/services/specs/foo", runtime.EncodeOrDie(latest.Codec, &api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
testService := api.Service{
|
||||
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex},
|
||||
|
@ -812,10 +812,10 @@ func TestEtcdListEndpoints(t *testing.T) {
|
|||
Node: &etcd.Node{
|
||||
Nodes: []*etcd.Node{
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:8345"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:8345"}}),
|
||||
},
|
||||
{
|
||||
Value: latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -841,7 +841,7 @@ func TestEtcdGetEndpoints(t *testing.T) {
|
|||
Endpoints: []string{"127.0.0.1:34855"},
|
||||
}
|
||||
|
||||
fakeClient.Set("/registry/services/endpoints/foo", latest.Codec.EncodeOrDie(endpoints), 0)
|
||||
fakeClient.Set("/registry/services/endpoints/foo", runtime.EncodeOrDie(latest.Codec, endpoints), 0)
|
||||
|
||||
got, err := registry.GetEndpoints("foo")
|
||||
if err != nil {
|
||||
|
@ -862,7 +862,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
|
|||
Endpoints: []string{"baz", "bar"},
|
||||
}
|
||||
|
||||
fakeClient.Set("/registry/services/endpoints/foo", latest.Codec.EncodeOrDie(&api.Endpoints{}), 0)
|
||||
fakeClient.Set("/registry/services/endpoints/foo", runtime.EncodeOrDie(latest.Codec, &api.Endpoints{}), 0)
|
||||
|
||||
err := registry.UpdateEndpoints(&endpoints)
|
||||
if err != nil {
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
||||
|
|
|
@ -20,42 +20,80 @@ import (
|
|||
"gopkg.in/v1/yaml"
|
||||
)
|
||||
|
||||
// EmbeddedObject must have an appropriate encoder and decoder functions, such that on the
|
||||
// wire, it's stored as a []byte, but in memory, the contained object is accessable as an
|
||||
// Object via the Get() function. Only valid API objects may be stored via EmbeddedObject.
|
||||
// The purpose of this is to allow an API object of type known only at runtime to be
|
||||
// embedded within other API objects.
|
||||
//
|
||||
// Define a Codec variable in your package and import the runtime package and
|
||||
// then use the commented section below
|
||||
|
||||
/*
|
||||
// EmbeddedObject implements a Codec specific version of an
|
||||
// embedded object.
|
||||
type EmbeddedObject struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
|
||||
obj, err := runtime.CodecUnmarshalJSON(Codec, b)
|
||||
a.Object = obj
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
|
||||
return runtime.CodecMarshalJSON(Codec, a.Object)
|
||||
}
|
||||
|
||||
// SetYAML implements the yaml.Setter interface.
|
||||
func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
||||
obj, ok := runtime.CodecSetYAML(Codec, tag, value)
|
||||
a.Object = obj
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetYAML implements the yaml.Getter interface.
|
||||
func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
|
||||
return runtime.CodecGetYAML(Codec, a.Object)
|
||||
}
|
||||
*/
|
||||
|
||||
// Encode()/Decode() are the canonical way of converting an API object to/from
|
||||
// wire format. This file provides utility functions which permit doing so
|
||||
// recursively, such that API objects of types known only at run time can be
|
||||
// embedded within other API types.
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
|
||||
func CodecUnmarshalJSON(codec Codec, b []byte) (Object, error) {
|
||||
// Handle JSON's "null": Decode() doesn't expect it.
|
||||
if len(b) == 4 && string(b) == "null" {
|
||||
a.Object = nil
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
obj, err := DefaultCodec.Decode(b)
|
||||
obj, err := codec.Decode(b)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
a.Object = obj
|
||||
return nil
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
|
||||
if a.Object == nil {
|
||||
func CodecMarshalJSON(codec Codec, obj Object) ([]byte, error) {
|
||||
if obj == nil {
|
||||
// Encode unset/nil objects as JSON's "null".
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
return DefaultCodec.Encode(a.Object)
|
||||
return codec.Encode(obj)
|
||||
}
|
||||
|
||||
// SetYAML implements the yaml.Setter interface.
|
||||
func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
||||
func CodecSetYAML(codec Codec, tag string, value interface{}) (Object, bool) {
|
||||
if value == nil {
|
||||
a.Object = nil
|
||||
return true
|
||||
return nil, true
|
||||
}
|
||||
// Why does the yaml package send value as a map[interface{}]interface{}?
|
||||
// It's especially frustrating because encoding/json does the right thing
|
||||
|
@ -67,22 +105,21 @@ func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
|||
if err != nil {
|
||||
panic("yaml can't reverse its own object")
|
||||
}
|
||||
obj, err := DefaultCodec.Decode(b)
|
||||
obj, err := codec.Decode(b)
|
||||
if err != nil {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
a.Object = obj
|
||||
return true
|
||||
return obj, true
|
||||
}
|
||||
|
||||
// GetYAML implements the yaml.Getter interface.
|
||||
func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
|
||||
if a.Object == nil {
|
||||
func CodecGetYAML(codec Codec, obj Object) (tag string, value interface{}) {
|
||||
if obj == nil {
|
||||
value = "null"
|
||||
return
|
||||
}
|
||||
// Encode returns JSON, which is conveniently a subset of YAML.
|
||||
v, err := DefaultCodec.Encode(a.Object)
|
||||
v, err := codec.Encode(obj)
|
||||
if err != nil {
|
||||
panic("impossible to encode API object!")
|
||||
}
|
||||
|
|
|
@ -14,16 +14,51 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var Codec = runtime.CodecFor(scheme, "v1test")
|
||||
|
||||
// EmbeddedObject implements a Codec specific version of an
|
||||
// embedded object.
|
||||
type EmbeddedObject struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
|
||||
obj, err := runtime.CodecUnmarshalJSON(Codec, b)
|
||||
a.Object = obj
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
|
||||
return runtime.CodecMarshalJSON(Codec, a.Object)
|
||||
}
|
||||
|
||||
// SetYAML implements the yaml.Setter interface.
|
||||
func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
||||
obj, ok := runtime.CodecSetYAML(Codec, tag, value)
|
||||
a.Object = obj
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetYAML implements the yaml.Getter interface.
|
||||
func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
|
||||
return runtime.CodecGetYAML(Codec, a.Object)
|
||||
}
|
||||
|
||||
type EmbeddedTest struct {
|
||||
JSONBase `yaml:",inline" json:",inline"`
|
||||
runtime.JSONBase `yaml:",inline" json:",inline"`
|
||||
Object EmbeddedObject `yaml:"object,omitempty" json:"object,omitempty"`
|
||||
EmptyObject EmbeddedObject `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
|
||||
}
|
||||
|
@ -31,21 +66,20 @@ type EmbeddedTest struct {
|
|||
func (*EmbeddedTest) IsAnAPIObject() {}
|
||||
|
||||
func TestEmbeddedObject(t *testing.T) {
|
||||
// TODO(dbsmith) fix EmbeddedObject to not use DefaultScheme.
|
||||
s := DefaultScheme
|
||||
s := scheme
|
||||
s.AddKnownTypes("", &EmbeddedTest{})
|
||||
s.AddKnownTypes("v1beta1", &EmbeddedTest{})
|
||||
s.AddKnownTypes("v1test", &EmbeddedTest{})
|
||||
|
||||
outer := &EmbeddedTest{
|
||||
JSONBase: JSONBase{ID: "outer"},
|
||||
JSONBase: runtime.JSONBase{ID: "outer"},
|
||||
Object: EmbeddedObject{
|
||||
&EmbeddedTest{
|
||||
JSONBase: JSONBase{ID: "inner"},
|
||||
JSONBase: runtime.JSONBase{ID: "inner"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
wire, err := s.Encode(outer)
|
||||
wire, err := s.EncodeToVersion(outer, "v1test")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected encode error '%v'", err)
|
||||
}
|
||||
|
|
|
@ -16,13 +16,23 @@ limitations under the License.
|
|||
|
||||
package runtime
|
||||
|
||||
// Codec defines methods for serializing and deserializing API objects.
|
||||
type Codec interface {
|
||||
Encode(obj Object) (data []byte, err error)
|
||||
// Decoder defines methods for deserializing API objects into a given type
|
||||
type Decoder interface {
|
||||
Decode(data []byte) (Object, error)
|
||||
DecodeInto(data []byte, obj Object) error
|
||||
}
|
||||
|
||||
// Encoder defines methods for serializing API objects into bytes
|
||||
type Encoder interface {
|
||||
Encode(obj Object) (data []byte, err error)
|
||||
}
|
||||
|
||||
// Codec defines methods for serializing and deserializing API objects.
|
||||
type Codec interface {
|
||||
Decoder
|
||||
Encoder
|
||||
}
|
||||
|
||||
// ResourceVersioner provides methods for setting and retrieving
|
||||
// the resource version from an API object.
|
||||
type ResourceVersioner interface {
|
||||
|
|
|
@ -17,16 +17,40 @@ limitations under the License.
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"gopkg.in/v1/yaml"
|
||||
)
|
||||
|
||||
var DefaultResourceVersioner ResourceVersioner = NewJSONBaseResourceVersioner()
|
||||
var DefaultScheme = NewScheme("", "v1beta1")
|
||||
var DefaultCodec Codec = DefaultScheme
|
||||
// codecWrapper implements encoding to an alternative
|
||||
// default version for a scheme.
|
||||
type codecWrapper struct {
|
||||
*Scheme
|
||||
version string
|
||||
}
|
||||
|
||||
// Encode implements Codec
|
||||
func (c *codecWrapper) Encode(obj Object) ([]byte, error) {
|
||||
return c.Scheme.EncodeToVersion(obj, c.version)
|
||||
}
|
||||
|
||||
// CodecFor returns a Codec that invokes Encode with the provided version.
|
||||
func CodecFor(scheme *Scheme, version string) Codec {
|
||||
return &codecWrapper{scheme, version}
|
||||
}
|
||||
|
||||
// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
|
||||
func EncodeOrDie(codec Codec, obj Object) string {
|
||||
bytes, err := codec.Encode(obj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
// Scheme defines methods for serializing and deserializing API objects. It
|
||||
// is an adaptation of conversion's Scheme for our API objects.
|
||||
|
@ -36,21 +60,13 @@ type Scheme struct {
|
|||
|
||||
// fromScope gets the input version, desired output version, and desired Scheme
|
||||
// from a conversion.Scope.
|
||||
func fromScope(s conversion.Scope) (inVersion, outVersion string, scheme *Scheme) {
|
||||
scheme = DefaultScheme
|
||||
func (self *Scheme) fromScope(s conversion.Scope) (inVersion, outVersion string, scheme *Scheme) {
|
||||
scheme = self
|
||||
inVersion = s.Meta().SrcVersion
|
||||
outVersion = s.Meta().DestVersion
|
||||
return inVersion, outVersion, scheme
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Set up a generic mapping between RawExtension and EmbeddedObject.
|
||||
DefaultScheme.AddConversionFuncs(
|
||||
embeddedObjectToRawExtension,
|
||||
rawExtensionToEmbeddedObject,
|
||||
)
|
||||
}
|
||||
|
||||
// emptyPlugin is used to copy the Kind field to and from plugin objects.
|
||||
type emptyPlugin struct {
|
||||
PluginBase `json:",inline" yaml:",inline"`
|
||||
|
@ -59,14 +75,14 @@ type emptyPlugin struct {
|
|||
// embeddedObjectToRawExtension does the conversion you would expect from the name, using the information
|
||||
// given in conversion.Scope. It's placed in the DefaultScheme as a ConversionFunc to enable plugins;
|
||||
// see the comment for RawExtension.
|
||||
func embeddedObjectToRawExtension(in *EmbeddedObject, out *RawExtension, s conversion.Scope) error {
|
||||
func (self *Scheme) embeddedObjectToRawExtension(in *EmbeddedObject, out *RawExtension, s conversion.Scope) error {
|
||||
if in.Object == nil {
|
||||
out.RawJSON = []byte("null")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Figure out the type and kind of the output object.
|
||||
_, outVersion, scheme := fromScope(s)
|
||||
_, outVersion, scheme := self.fromScope(s)
|
||||
_, kind, err := scheme.raw.ObjectVersionAndKind(in.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -107,13 +123,13 @@ func embeddedObjectToRawExtension(in *EmbeddedObject, out *RawExtension, s conve
|
|||
// rawExtensionToEmbeddedObject does the conversion you would expect from the name, using the information
|
||||
// given in conversion.Scope. It's placed in the DefaultScheme as a ConversionFunc to enable plugins;
|
||||
// see the comment for RawExtension.
|
||||
func rawExtensionToEmbeddedObject(in *RawExtension, out *EmbeddedObject, s conversion.Scope) error {
|
||||
func (self *Scheme) rawExtensionToEmbeddedObject(in *RawExtension, out *EmbeddedObject, s conversion.Scope) error {
|
||||
if len(in.RawJSON) == 4 && string(in.RawJSON) == "null" {
|
||||
out.Object = nil
|
||||
return nil
|
||||
}
|
||||
// Figure out the type and kind of the output object.
|
||||
inVersion, outVersion, scheme := fromScope(s)
|
||||
inVersion, outVersion, scheme := self.fromScope(s)
|
||||
_, kind, err := scheme.raw.DataVersionAndKind(in.RawJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -153,13 +169,15 @@ func rawExtensionToEmbeddedObject(in *RawExtension, out *EmbeddedObject, s conve
|
|||
return nil
|
||||
}
|
||||
|
||||
// NewScheme creates a new Scheme. A default scheme is provided and accessible
|
||||
// as the "DefaultScheme" variable.
|
||||
func NewScheme(internalVersion, externalVersion string) *Scheme {
|
||||
// NewScheme creates a new Scheme. This scheme is pluggable by default.
|
||||
func NewScheme() *Scheme {
|
||||
s := &Scheme{conversion.NewScheme()}
|
||||
s.raw.InternalVersion = internalVersion
|
||||
s.raw.ExternalVersion = externalVersion
|
||||
s.raw.InternalVersion = ""
|
||||
s.raw.MetaInsertionFactory = metaInsertion{}
|
||||
s.raw.AddConversionFuncs(
|
||||
s.embeddedObjectToRawExtension,
|
||||
s.rawExtensionToEmbeddedObject,
|
||||
)
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -180,6 +198,10 @@ func (s *Scheme) AddKnownTypeWithName(version, kind string, obj Object) {
|
|||
s.raw.AddKnownTypeWithName(version, kind, obj)
|
||||
}
|
||||
|
||||
func (s *Scheme) KnownTypes(version string) map[string]reflect.Type {
|
||||
return s.raw.KnownTypes(version)
|
||||
}
|
||||
|
||||
// New returns a new API object of the given version ("" for internal
|
||||
// representation) and name, or an error if it hasn't been registered.
|
||||
func (s *Scheme) New(versionName, typeName string) (Object, error) {
|
||||
|
@ -236,12 +258,7 @@ func FindJSONBase(obj Object) (JSONBaseInterface, error) {
|
|||
return g, nil
|
||||
}
|
||||
|
||||
// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
|
||||
func (s *Scheme) EncodeOrDie(obj Object) string {
|
||||
return s.raw.EncodeOrDie(obj)
|
||||
}
|
||||
|
||||
// Encode turns the given api object into an appropriate JSON string.
|
||||
// EncodeToVersion turns the given api object into an appropriate JSON string.
|
||||
// Will return an error if the object doesn't have an embedded JSONBase.
|
||||
// Obj may be a pointer to a struct, or a struct. If a struct, a copy
|
||||
// must be made. If a pointer, the object may be modified before encoding,
|
||||
|
@ -269,17 +286,6 @@ func (s *Scheme) EncodeOrDie(obj Object) string {
|
|||
// change the memory format yet not break compatibility with any stored
|
||||
// objects, whether they be in our storage layer (e.g., etcd), or in user's
|
||||
// config files.
|
||||
//
|
||||
// TODO/next steps: When we add our second versioned type, this package will
|
||||
// need a version of Encode that lets you choose the wire version. A configurable
|
||||
// default will be needed, to allow operating in clusters that haven't yet
|
||||
// upgraded.
|
||||
//
|
||||
func (s *Scheme) Encode(obj Object) (data []byte, err error) {
|
||||
return s.raw.Encode(obj)
|
||||
}
|
||||
|
||||
// EncodeToVersion is like Encode, but lets you specify the destination version.
|
||||
func (s *Scheme) EncodeToVersion(obj Object, destVersion string) (data []byte, err error) {
|
||||
return s.raw.EncodeToVersion(obj, destVersion)
|
||||
}
|
||||
|
@ -332,10 +338,10 @@ func (s *Scheme) DecodeInto(data []byte, obj Object) error {
|
|||
return s.raw.DecodeInto(data, obj)
|
||||
}
|
||||
|
||||
// Does a deep copy of an API object. Useful mostly for tests.
|
||||
// Copy does a deep copy of an API object. Useful mostly for tests.
|
||||
// TODO(dbsmith): implement directly instead of via Encode/Decode
|
||||
func (s *Scheme) Copy(obj Object) (Object, error) {
|
||||
data, err := s.Encode(obj)
|
||||
data, err := s.EncodeToVersion(obj, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -350,6 +356,26 @@ func (s *Scheme) CopyOrDie(obj Object) Object {
|
|||
return newObj
|
||||
}
|
||||
|
||||
func ObjectDiff(a, b Object) string {
|
||||
ab, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("a: %v", err))
|
||||
}
|
||||
bb, err := json.Marshal(b)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("b: %v", err))
|
||||
}
|
||||
return util.StringDiff(string(ab), string(bb))
|
||||
|
||||
// An alternate diff attempt, in case json isn't showing you
|
||||
// the difference. (reflect.DeepEqual makes a distinction between
|
||||
// nil and empty slices, for example.)
|
||||
return util.StringDiff(
|
||||
fmt.Sprintf("%#v", a),
|
||||
fmt.Sprintf("%#v", b),
|
||||
)
|
||||
}
|
||||
|
||||
// metaInsertion implements conversion.MetaInsertionFactory, which lets the conversion
|
||||
// package figure out how to encode our object's types and versions. These fields are
|
||||
// located in our JSONBase.
|
||||
|
|
|
@ -43,14 +43,15 @@ func (*InternalSimple) IsAnAPIObject() {}
|
|||
func (*ExternalSimple) IsAnAPIObject() {}
|
||||
|
||||
func TestScheme(t *testing.T) {
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
|
||||
|
||||
internalToExternalCalls := 0
|
||||
externalToInternalCalls := 0
|
||||
|
||||
// Register functions to verify that scope.Meta() gets set correctly.
|
||||
err := runtime.DefaultScheme.AddConversionFuncs(
|
||||
err := scheme.AddConversionFuncs(
|
||||
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error {
|
||||
if e, a := "", scope.Meta().SrcVersion; e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
|
@ -85,10 +86,10 @@ func TestScheme(t *testing.T) {
|
|||
|
||||
// Test Encode, Decode, and DecodeInto
|
||||
obj := runtime.Object(simple)
|
||||
data, err := runtime.DefaultScheme.EncodeToVersion(obj, "externalVersion")
|
||||
obj2, err2 := runtime.DefaultScheme.Decode(data)
|
||||
data, err := scheme.EncodeToVersion(obj, "externalVersion")
|
||||
obj2, err2 := scheme.Decode(data)
|
||||
obj3 := &InternalSimple{}
|
||||
err3 := runtime.DefaultScheme.DecodeInto(data, obj3)
|
||||
err3 := scheme.DecodeInto(data, obj3)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v' '%v'", err, err2, err3)
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ func TestScheme(t *testing.T) {
|
|||
|
||||
// Test Convert
|
||||
external := &ExternalSimple{}
|
||||
err = runtime.DefaultScheme.Convert(simple, external)
|
||||
err = scheme.Convert(simple, external)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
@ -123,12 +124,13 @@ func TestScheme(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBadJSONRejection(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
badJSONMissingKind := []byte(`{ }`)
|
||||
if _, err := runtime.DefaultScheme.Decode(badJSONMissingKind); err == nil {
|
||||
if _, err := scheme.Decode(badJSONMissingKind); err == nil {
|
||||
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
||||
}
|
||||
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
||||
if _, err1 := runtime.DefaultScheme.Decode(badJSONUnknownType); err1 == nil {
|
||||
if _, err1 := scheme.Decode(badJSONUnknownType); err1 == nil {
|
||||
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
||||
}
|
||||
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
||||
|
@ -163,12 +165,13 @@ func (*ExternalExtensionType) IsAnAPIObject() {}
|
|||
func (*InternalExtensionType) IsAnAPIObject() {}
|
||||
|
||||
func TestExtensionMapping(t *testing.T) {
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("", "ExtensionType", &InternalExtensionType{})
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("", "A", &ExtensionA{})
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("", "B", &ExtensionB{})
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("testExternal", "ExtensionType", &ExternalExtensionType{})
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("testExternal", "A", &ExtensionA{})
|
||||
runtime.DefaultScheme.AddKnownTypeWithName("testExternal", "B", &ExtensionB{})
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "ExtensionType", &InternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("", "A", &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName("", "B", &ExtensionB{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "ExtensionType", &ExternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "A", &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "B", &ExtensionB{})
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
|
@ -187,14 +190,14 @@ func TestExtensionMapping(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, item := range table {
|
||||
gotEncoded, err := runtime.DefaultScheme.EncodeToVersion(item.obj, "testExternal")
|
||||
gotEncoded, err := scheme.EncodeToVersion(item.obj, "testExternal")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%#v)", err, item.obj)
|
||||
} else if e, a := item.encoded, string(gotEncoded); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
gotDecoded, err := runtime.DefaultScheme.Decode([]byte(item.encoded))
|
||||
gotDecoded, err := scheme.Decode([]byte(item.encoded))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%v)", err, item.encoded)
|
||||
} else if e, a := item.obj, gotDecoded; !reflect.DeepEqual(e, a) {
|
||||
|
@ -209,3 +212,25 @@ func TestExtensionMapping(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
|
||||
codec := runtime.CodecFor(scheme, "externalVersion")
|
||||
test := &InternalSimple{
|
||||
TestString: "I'm the same",
|
||||
}
|
||||
obj := runtime.Object(test)
|
||||
data, err := codec.Encode(obj)
|
||||
obj2, err2 := codec.Decode(data)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||
}
|
||||
if _, ok := obj2.(*InternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !reflect.DeepEqual(obj2, test) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", &test, obj2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
|
@ -42,13 +43,14 @@ type TestResource struct {
|
|||
func (*TestResource) IsAnAPIObject() {}
|
||||
|
||||
var scheme *runtime.Scheme
|
||||
var codec = latest.Codec
|
||||
var versioner = runtime.DefaultResourceVersioner
|
||||
var codec runtime.Codec
|
||||
var versioner = runtime.NewJSONBaseResourceVersioner()
|
||||
|
||||
func init() {
|
||||
scheme = runtime.NewScheme("", "v1beta1")
|
||||
scheme = runtime.NewScheme()
|
||||
scheme.AddKnownTypes("", &TestResource{})
|
||||
scheme.AddKnownTypes("v1beta1", &TestResource{})
|
||||
codec = runtime.CodecFor(scheme, "v1beta1")
|
||||
}
|
||||
|
||||
func TestIsEtcdNotFound(t *testing.T) {
|
||||
|
@ -93,7 +95,7 @@ func TestExtractList(t *testing.T) {
|
|||
}
|
||||
|
||||
var got []api.Pod
|
||||
helper := EtcdHelper{fakeClient, codec, versioner}
|
||||
helper := EtcdHelper{fakeClient, latest.Codec, versioner}
|
||||
resourceVersion := uint64(0)
|
||||
err := helper.ExtractList("/some/key", &got, &resourceVersion)
|
||||
if err != nil {
|
||||
|
@ -114,7 +116,7 @@ func TestExtractObj(t *testing.T) {
|
|||
fakeClient := NewFakeEtcdClient(t)
|
||||
expect := api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
fakeClient.Set("/some/key", util.EncodeJSON(expect), 0)
|
||||
helper := EtcdHelper{fakeClient, codec, versioner}
|
||||
helper := EtcdHelper{fakeClient, latest.Codec, versioner}
|
||||
var got api.Pod
|
||||
err := helper.ExtractObj("/some/key", &got, false)
|
||||
if err != nil {
|
||||
|
@ -168,12 +170,12 @@ func TestExtractObjNotFoundErr(t *testing.T) {
|
|||
func TestSetObj(t *testing.T) {
|
||||
obj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
helper := EtcdHelper{fakeClient, codec, versioner}
|
||||
helper := EtcdHelper{fakeClient, latest.Codec, versioner}
|
||||
err := helper.SetObj("/some/key", obj)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
}
|
||||
data, err := codec.Encode(obj)
|
||||
data, err := latest.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
}
|
||||
|
@ -191,18 +193,18 @@ func TestSetObjWithVersion(t *testing.T) {
|
|||
fakeClient.Data["/some/key"] = EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: latest.Codec.EncodeOrDie(obj),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, obj),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
helper := EtcdHelper{fakeClient, codec, versioner}
|
||||
helper := EtcdHelper{fakeClient, latest.Codec, versioner}
|
||||
err := helper.SetObj("/some/key", obj)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %#v", err)
|
||||
}
|
||||
data, err := codec.Encode(obj)
|
||||
data, err := latest.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %#v", err)
|
||||
}
|
||||
|
@ -216,12 +218,12 @@ func TestSetObjWithVersion(t *testing.T) {
|
|||
func TestSetObjWithoutResourceVersioner(t *testing.T) {
|
||||
obj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
helper := EtcdHelper{fakeClient, codec, nil}
|
||||
helper := EtcdHelper{fakeClient, latest.Codec, nil}
|
||||
err := helper.SetObj("/some/key", obj)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
}
|
||||
data, err := codec.Encode(obj)
|
||||
data, err := latest.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
}
|
||||
|
@ -235,7 +237,6 @@ func TestSetObjWithoutResourceVersioner(t *testing.T) {
|
|||
func TestAtomicUpdate(t *testing.T) {
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
fakeClient.TestIndex = true
|
||||
codec := scheme
|
||||
helper := EtcdHelper{fakeClient, codec, runtime.NewJSONBaseResourceVersioner()}
|
||||
|
||||
// Create a new node.
|
||||
|
@ -290,7 +291,7 @@ func TestAtomicUpdate(t *testing.T) {
|
|||
func TestAtomicUpdateNoChange(t *testing.T) {
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
fakeClient.TestIndex = true
|
||||
helper := EtcdHelper{fakeClient, scheme, runtime.NewJSONBaseResourceVersioner()}
|
||||
helper := EtcdHelper{fakeClient, codec, runtime.NewJSONBaseResourceVersioner()}
|
||||
|
||||
// Create a new node.
|
||||
fakeClient.ExpectNotFoundGet("/some/key")
|
||||
|
@ -321,7 +322,6 @@ func TestAtomicUpdateNoChange(t *testing.T) {
|
|||
func TestAtomicUpdate_CreateCollision(t *testing.T) {
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
fakeClient.TestIndex = true
|
||||
codec := scheme
|
||||
helper := EtcdHelper{fakeClient, codec, runtime.NewJSONBaseResourceVersioner()}
|
||||
|
||||
fakeClient.ExpectNotFoundGet("/some/key")
|
||||
|
|
|
@ -23,12 +23,14 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func TestWatchInterpretations(t *testing.T) {
|
||||
codec := latest.Codec
|
||||
// Declare some pods to make the test cases compact.
|
||||
podFoo := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
podBar := &api.Pod{JSONBase: api.JSONBase{ID: "bar"}}
|
||||
|
@ -48,62 +50,62 @@ func TestWatchInterpretations(t *testing.T) {
|
|||
}{
|
||||
"create": {
|
||||
actions: []string{"create", "get"},
|
||||
nodeValue: latest.Codec.EncodeOrDie(podBar),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podBar),
|
||||
expectEmit: true,
|
||||
expectType: watch.Added,
|
||||
expectObject: podBar,
|
||||
},
|
||||
"create but filter blocks": {
|
||||
actions: []string{"create", "get"},
|
||||
nodeValue: latest.Codec.EncodeOrDie(podFoo),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podFoo),
|
||||
expectEmit: false,
|
||||
},
|
||||
"delete": {
|
||||
actions: []string{"delete"},
|
||||
prevNodeValue: latest.Codec.EncodeOrDie(podBar),
|
||||
prevNodeValue: runtime.EncodeOrDie(codec, podBar),
|
||||
expectEmit: true,
|
||||
expectType: watch.Deleted,
|
||||
expectObject: podBar,
|
||||
},
|
||||
"delete but filter blocks": {
|
||||
actions: []string{"delete"},
|
||||
nodeValue: latest.Codec.EncodeOrDie(podFoo),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podFoo),
|
||||
expectEmit: false,
|
||||
},
|
||||
"modify appears to create 1": {
|
||||
actions: []string{"set", "compareAndSwap"},
|
||||
nodeValue: latest.Codec.EncodeOrDie(podBar),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podBar),
|
||||
expectEmit: true,
|
||||
expectType: watch.Added,
|
||||
expectObject: podBar,
|
||||
},
|
||||
"modify appears to create 2": {
|
||||
actions: []string{"set", "compareAndSwap"},
|
||||
prevNodeValue: latest.Codec.EncodeOrDie(podFoo),
|
||||
nodeValue: latest.Codec.EncodeOrDie(podBar),
|
||||
prevNodeValue: runtime.EncodeOrDie(codec, podFoo),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podBar),
|
||||
expectEmit: true,
|
||||
expectType: watch.Added,
|
||||
expectObject: podBar,
|
||||
},
|
||||
"modify appears to delete": {
|
||||
actions: []string{"set", "compareAndSwap"},
|
||||
prevNodeValue: latest.Codec.EncodeOrDie(podBar),
|
||||
nodeValue: latest.Codec.EncodeOrDie(podFoo),
|
||||
prevNodeValue: runtime.EncodeOrDie(codec, podBar),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podFoo),
|
||||
expectEmit: true,
|
||||
expectType: watch.Deleted,
|
||||
expectObject: podBar, // Should return last state that passed the filter!
|
||||
},
|
||||
"modify modifies": {
|
||||
actions: []string{"set", "compareAndSwap"},
|
||||
prevNodeValue: latest.Codec.EncodeOrDie(podBar),
|
||||
nodeValue: latest.Codec.EncodeOrDie(podBaz),
|
||||
prevNodeValue: runtime.EncodeOrDie(codec, podBar),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podBaz),
|
||||
expectEmit: true,
|
||||
expectType: watch.Modified,
|
||||
expectObject: podBaz,
|
||||
},
|
||||
"modify ignores": {
|
||||
actions: []string{"set", "compareAndSwap"},
|
||||
nodeValue: latest.Codec.EncodeOrDie(podFoo),
|
||||
nodeValue: runtime.EncodeOrDie(codec, podFoo),
|
||||
expectEmit: false,
|
||||
},
|
||||
}
|
||||
|
@ -197,6 +199,7 @@ func TestWatchInterpretation_ResponseBadData(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
codec := latest.Codec
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{}
|
||||
h := EtcdHelper{fakeClient, codec, versioner}
|
||||
|
@ -243,6 +246,7 @@ func TestWatch(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWatchEtcdState(t *testing.T) {
|
||||
codec := latest.Codec
|
||||
type T struct {
|
||||
Type watch.EventType
|
||||
Endpoints []string
|
||||
|
@ -259,7 +263,7 @@ func TestWatchEtcdState(t *testing.T) {
|
|||
{
|
||||
Action: "create",
|
||||
Node: &etcd.Node{
|
||||
Value: string(latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
Value: string(runtime.EncodeOrDie(codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -273,12 +277,12 @@ func TestWatchEtcdState(t *testing.T) {
|
|||
{
|
||||
Action: "compareAndSwap",
|
||||
Node: &etcd.Node{
|
||||
Value: string(latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
||||
Value: string(runtime.EncodeOrDie(codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 2,
|
||||
},
|
||||
PrevNode: &etcd.Node{
|
||||
Value: string(latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
Value: string(runtime.EncodeOrDie(codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
|
@ -295,7 +299,7 @@ func TestWatchEtcdState(t *testing.T) {
|
|||
R: &etcd.Response{
|
||||
Action: "get",
|
||||
Node: &etcd.Node{
|
||||
Value: string(latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
Value: string(runtime.EncodeOrDie(codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
|
@ -308,12 +312,12 @@ func TestWatchEtcdState(t *testing.T) {
|
|||
{
|
||||
Action: "compareAndSwap",
|
||||
Node: &etcd.Node{
|
||||
Value: string(latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
||||
Value: string(runtime.EncodeOrDie(codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 2,
|
||||
},
|
||||
PrevNode: &etcd.Node{
|
||||
Value: string(latest.Codec.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
Value: string(runtime.EncodeOrDie(codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
|
@ -359,6 +363,7 @@ func TestWatchEtcdState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWatchFromZeroIndex(t *testing.T) {
|
||||
codec := latest.Codec
|
||||
pod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
|
||||
testCases := map[string]struct {
|
||||
|
@ -370,7 +375,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
|
|||
EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: latest.Codec.EncodeOrDie(pod),
|
||||
Value: runtime.EncodeOrDie(codec, pod),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
|
@ -385,7 +390,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
|
|||
EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: latest.Codec.EncodeOrDie(pod),
|
||||
Value: runtime.EncodeOrDie(codec, pod),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 2,
|
||||
},
|
||||
|
@ -434,6 +439,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWatchListFromZeroIndex(t *testing.T) {
|
||||
codec := latest.Codec
|
||||
pod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
|
||||
fakeClient := NewFakeEtcdClient(t)
|
||||
|
@ -443,13 +449,13 @@ func TestWatchListFromZeroIndex(t *testing.T) {
|
|||
Dir: true,
|
||||
Nodes: etcd.Nodes{
|
||||
&etcd.Node{
|
||||
Value: latest.Codec.EncodeOrDie(pod),
|
||||
Value: runtime.EncodeOrDie(codec, pod),
|
||||
CreatedIndex: 1,
|
||||
ModifiedIndex: 1,
|
||||
Nodes: etcd.Nodes{},
|
||||
},
|
||||
&etcd.Node{
|
||||
Value: latest.Codec.EncodeOrDie(pod),
|
||||
Value: runtime.EncodeOrDie(codec, pod),
|
||||
CreatedIndex: 2,
|
||||
ModifiedIndex: 2,
|
||||
Nodes: etcd.Nodes{},
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
|
@ -113,7 +114,7 @@ func TestPollMinions(t *testing.T) {
|
|||
ml := &api.MinionList{Items: item.minions}
|
||||
handler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
ResponseBody: latest.Codec.EncodeOrDie(ml),
|
||||
ResponseBody: runtime.EncodeOrDie(latest.Codec, ml),
|
||||
T: t,
|
||||
}
|
||||
mux := http.NewServeMux()
|
||||
|
@ -140,7 +141,7 @@ func TestDefaultErrorFunc(t *testing.T) {
|
|||
testPod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
handler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
ResponseBody: latest.Codec.EncodeOrDie(testPod),
|
||||
ResponseBody: runtime.EncodeOrDie(latest.Codec, testPod),
|
||||
T: t,
|
||||
}
|
||||
mux := http.NewServeMux()
|
||||
|
@ -259,7 +260,7 @@ func TestBind(t *testing.T) {
|
|||
t.Errorf("Unexpected error: %v", err)
|
||||
continue
|
||||
}
|
||||
expectedBody := latest.Codec.EncodeOrDie(item.binding)
|
||||
expectedBody := runtime.EncodeOrDie(latest.Codec, item.binding)
|
||||
handler.ValidateRequest(t, "/api/v1beta1/bindings", "POST", &expectedBody)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
|
@ -90,9 +92,9 @@ func TestExtractObj(t *testing.T) {
|
|||
|
||||
func TestWatch(t *testing.T) {
|
||||
client := newEtcdClient()
|
||||
helper := tools.EtcdHelper{Client: client, Codec: latest.Codec, ResourceVersioner: runtime.DefaultResourceVersioner}
|
||||
helper := tools.EtcdHelper{Client: client, Codec: latest.Codec, ResourceVersioner: latest.ResourceVersioner}
|
||||
withEtcdKey(func(key string) {
|
||||
resp, err := client.Set(key, latest.Codec.EncodeOrDie(&api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
resp, err := client.Set(key, runtime.EncodeOrDie(v1beta1.Codec, &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue