mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-12-16 21:07:22 +00:00
Merge pull request #1202 from lavalamp/fixApi3
Please expedite: the rarely attempted interface{} -> runtime.Object rename
This commit is contained in:
@@ -179,7 +179,7 @@ func runReplicationControllerTest(c *client.Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glog.Infof("Creating replication controllers")
|
glog.Infof("Creating replication controllers")
|
||||||
if _, err := c.CreateReplicationController(controllerRequest); err != nil {
|
if _, err := c.CreateReplicationController(&controllerRequest); err != nil {
|
||||||
glog.Fatalf("Unexpected error: %#v", err)
|
glog.Fatalf("Unexpected error: %#v", err)
|
||||||
}
|
}
|
||||||
glog.Infof("Done creating replication controllers")
|
glog.Infof("Done creating replication controllers")
|
||||||
@@ -194,7 +194,7 @@ func runReplicationControllerTest(c *client.Client) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("FAILED: unable to get pods to list: %v", err)
|
glog.Fatalf("FAILED: unable to get pods to list: %v", err)
|
||||||
}
|
}
|
||||||
if err := wait.Poll(time.Second, time.Second*10, podsOnMinions(c, pods)); err != nil {
|
if err := wait.Poll(time.Second, time.Second*10, podsOnMinions(c, *pods)); err != nil {
|
||||||
glog.Fatalf("FAILED: pods never started running %v", err)
|
glog.Fatalf("FAILED: pods never started running %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ func runReplicationControllerTest(c *client.Client) {
|
|||||||
func runAtomicPutTest(c *client.Client) {
|
func runAtomicPutTest(c *client.Client) {
|
||||||
var svc api.Service
|
var svc api.Service
|
||||||
err := c.Post().Path("services").Body(
|
err := c.Post().Path("services").Body(
|
||||||
api.Service{
|
&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "atomicservice", APIVersion: "v1beta1"},
|
JSONBase: api.JSONBase{ID: "atomicservice", APIVersion: "v1beta1"},
|
||||||
Port: 12345,
|
Port: 12345,
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ var (
|
|||||||
imageName = flag.String("image", "", "Image used when updating a replicationController. Will apply to the first container in the pod template.")
|
imageName = flag.String("image", "", "Image used when updating a replicationController. Will apply to the first container in the pod template.")
|
||||||
)
|
)
|
||||||
|
|
||||||
var parser = kubecfg.NewParser(map[string]interface{}{
|
var parser = kubecfg.NewParser(map[string]runtime.Object{
|
||||||
"pods": api.Pod{},
|
"pods": &api.Pod{},
|
||||||
"services": api.Service{},
|
"services": &api.Service{},
|
||||||
"replicationControllers": api.ReplicationController{},
|
"replicationControllers": &api.ReplicationController{},
|
||||||
"minions": api.Minion{},
|
"minions": &api.Minion{},
|
||||||
})
|
})
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
@@ -266,7 +266,7 @@ func executeAPIRequest(method string, c *client.Client) bool {
|
|||||||
if setBody {
|
if setBody {
|
||||||
if version != 0 {
|
if version != 0 {
|
||||||
data := readConfig(storage)
|
data := readConfig(storage)
|
||||||
obj, err := runtime.Decode(data)
|
obj, err := runtime.DefaultCodec.Decode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("error setting resource version: %v", err)
|
glog.Fatalf("error setting resource version: %v", err)
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,7 @@ func executeAPIRequest(method string, c *client.Client) bool {
|
|||||||
glog.Fatalf("error setting resource version: %v", err)
|
glog.Fatalf("error setting resource version: %v", err)
|
||||||
}
|
}
|
||||||
jsonBase.SetResourceVersion(version)
|
jsonBase.SetResourceVersion(version)
|
||||||
data, err = runtime.Encode(obj)
|
data, err = runtime.DefaultCodec.Encode(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("error setting resource version: %v", err)
|
glog.Fatalf("error setting resource version: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import (
|
|||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateObject(obj interface{}) (errors []error) {
|
func validateObject(obj runtime.Object) (errors []error) {
|
||||||
switch t := obj.(type) {
|
switch t := obj.(type) {
|
||||||
case *api.ReplicationController:
|
case *api.ReplicationController:
|
||||||
errors = validation.ValidateManifest(&t.DesiredState.PodTemplate.DesiredState.Manifest)
|
errors = validation.ValidateManifest(&t.DesiredState.PodTemplate.DesiredState.Manifest)
|
||||||
@@ -85,7 +85,7 @@ func walkJSONFiles(inDir string, fn func(name, path string, data []byte)) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestApiExamples(t *testing.T) {
|
func TestApiExamples(t *testing.T) {
|
||||||
expected := map[string]interface{}{
|
expected := map[string]runtime.Object{
|
||||||
"controller": &api.ReplicationController{},
|
"controller": &api.ReplicationController{},
|
||||||
"controller-list": &api.ReplicationControllerList{},
|
"controller-list": &api.ReplicationControllerList{},
|
||||||
"pod": &api.Pod{},
|
"pod": &api.Pod{},
|
||||||
@@ -103,7 +103,7 @@ func TestApiExamples(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
tested += 1
|
tested += 1
|
||||||
if err := runtime.DecodeInto(data, expectedType); err != nil {
|
if err := runtime.DefaultCodec.DecodeInto(data, expectedType); err != nil {
|
||||||
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func TestApiExamples(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExamples(t *testing.T) {
|
func TestExamples(t *testing.T) {
|
||||||
expected := map[string]interface{}{
|
expected := map[string]runtime.Object{
|
||||||
"frontend-controller": &api.ReplicationController{},
|
"frontend-controller": &api.ReplicationController{},
|
||||||
"redis-slave-controller": &api.ReplicationController{},
|
"redis-slave-controller": &api.ReplicationController{},
|
||||||
"redis-master": &api.Pod{},
|
"redis-master": &api.Pod{},
|
||||||
@@ -137,7 +137,7 @@ func TestExamples(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
tested += 1
|
tested += 1
|
||||||
if err := runtime.DecodeInto(data, expectedType); err != nil {
|
if err := runtime.DefaultCodec.DecodeInto(data, expectedType); err != nil {
|
||||||
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -168,14 +168,14 @@ func TestReadme(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, json := range match[1:] {
|
for _, json := range match[1:] {
|
||||||
expectedType := &api.Pod{}
|
expectedType := &api.Pod{}
|
||||||
if err := runtime.DecodeInto([]byte(json), expectedType); err != nil {
|
if err := runtime.DefaultCodec.DecodeInto([]byte(json), expectedType); err != nil {
|
||||||
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if errors := validateObject(expectedType); len(errors) > 0 {
|
if errors := validateObject(expectedType); len(errors) > 0 {
|
||||||
t.Errorf("%s did not validate correctly: %v", path, errors)
|
t.Errorf("%s did not validate correctly: %v", path, errors)
|
||||||
}
|
}
|
||||||
encoded, err := runtime.Encode(expectedType)
|
encoded, err := runtime.DefaultCodec.Encode(expectedType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Could not encode object: %v", err)
|
t.Errorf("Could not encode object: %v", err)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -21,21 +21,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.AddKnownTypes("",
|
runtime.DefaultScheme.AddKnownTypes("",
|
||||||
PodList{},
|
&PodList{},
|
||||||
Pod{},
|
&Pod{},
|
||||||
ReplicationControllerList{},
|
&ReplicationControllerList{},
|
||||||
ReplicationController{},
|
&ReplicationController{},
|
||||||
ServiceList{},
|
&ServiceList{},
|
||||||
Service{},
|
&Service{},
|
||||||
MinionList{},
|
&MinionList{},
|
||||||
Minion{},
|
&Minion{},
|
||||||
Status{},
|
&Status{},
|
||||||
ServerOpList{},
|
&ServerOpList{},
|
||||||
ServerOp{},
|
&ServerOp{},
|
||||||
ContainerManifestList{},
|
&ContainerManifestList{},
|
||||||
Endpoints{},
|
&Endpoints{},
|
||||||
EndpointsList{},
|
&EndpointsList{},
|
||||||
Binding{},
|
&Binding{},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
func objDiff(a, b interface{}) string {
|
func objDiff(a, b runtime.Object) string {
|
||||||
ab, err := json.Marshal(a)
|
ab, err := json.Marshal(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("a")
|
panic("a")
|
||||||
@@ -105,7 +105,7 @@ func objDiff(a, b interface{}) string {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTest(t *testing.T, source interface{}) {
|
func runTest(t *testing.T, source runtime.Object) {
|
||||||
name := reflect.TypeOf(source).Elem().Name()
|
name := reflect.TypeOf(source).Elem().Name()
|
||||||
apiObjectFuzzer.Fuzz(source)
|
apiObjectFuzzer.Fuzz(source)
|
||||||
j, err := runtime.FindJSONBase(source)
|
j, err := runtime.FindJSONBase(source)
|
||||||
@@ -115,13 +115,13 @@ func runTest(t *testing.T, source interface{}) {
|
|||||||
j.SetKind("")
|
j.SetKind("")
|
||||||
j.SetAPIVersion("")
|
j.SetAPIVersion("")
|
||||||
|
|
||||||
data, err := runtime.Encode(source)
|
data, err := runtime.DefaultCodec.Encode(source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%v: %v (%#v)", name, err, source)
|
t.Errorf("%v: %v (%#v)", name, err, source)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
obj2, err := runtime.Decode(data)
|
obj2, err := runtime.DefaultCodec.Decode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%v: %v", name, err)
|
t.Errorf("%v: %v", name, err)
|
||||||
return
|
return
|
||||||
@@ -131,8 +131,8 @@ func runTest(t *testing.T, source interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface()
|
obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface().(runtime.Object)
|
||||||
err = runtime.DecodeInto(data, obj3)
|
err = runtime.DefaultCodec.DecodeInto(data, obj3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("2: %v: %v", name, err)
|
t.Errorf("2: %v: %v", name, err)
|
||||||
return
|
return
|
||||||
@@ -145,7 +145,7 @@ func runTest(t *testing.T, source interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTypes(t *testing.T) {
|
func TestTypes(t *testing.T) {
|
||||||
table := []interface{}{
|
table := []runtime.Object{
|
||||||
&api.PodList{},
|
&api.PodList{},
|
||||||
&api.Pod{},
|
&api.Pod{},
|
||||||
&api.ServiceList{},
|
&api.ServiceList{},
|
||||||
@@ -169,31 +169,13 @@ func TestTypes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncode_NonPtr(t *testing.T) {
|
|
||||||
pod := api.Pod{
|
|
||||||
Labels: map[string]string{"name": "foo"},
|
|
||||||
}
|
|
||||||
obj := interface{}(pod)
|
|
||||||
data, err := runtime.Encode(obj)
|
|
||||||
obj2, err2 := runtime.Decode(data)
|
|
||||||
if err != nil || err2 != nil {
|
|
||||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
|
||||||
}
|
|
||||||
if _, ok := obj2.(*api.Pod); !ok {
|
|
||||||
t.Fatalf("Got wrong type")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(obj2, &pod) {
|
|
||||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", &pod, obj2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEncode_Ptr(t *testing.T) {
|
func TestEncode_Ptr(t *testing.T) {
|
||||||
pod := &api.Pod{
|
pod := &api.Pod{
|
||||||
Labels: map[string]string{"name": "foo"},
|
Labels: map[string]string{"name": "foo"},
|
||||||
}
|
}
|
||||||
obj := interface{}(pod)
|
obj := runtime.Object(pod)
|
||||||
data, err := runtime.Encode(obj)
|
data, err := runtime.DefaultCodec.Encode(obj)
|
||||||
obj2, err2 := runtime.Decode(data)
|
obj2, err2 := runtime.DefaultCodec.Decode(data)
|
||||||
if err != nil || err2 != nil {
|
if err != nil || err2 != nil {
|
||||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||||
}
|
}
|
||||||
@@ -207,11 +189,11 @@ func TestEncode_Ptr(t *testing.T) {
|
|||||||
|
|
||||||
func TestBadJSONRejection(t *testing.T) {
|
func TestBadJSONRejection(t *testing.T) {
|
||||||
badJSONMissingKind := []byte(`{ }`)
|
badJSONMissingKind := []byte(`{ }`)
|
||||||
if _, err := runtime.Decode(badJSONMissingKind); err == nil {
|
if _, err := runtime.DefaultCodec.Decode(badJSONMissingKind); err == nil {
|
||||||
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
||||||
}
|
}
|
||||||
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
||||||
if _, err1 := runtime.Decode(badJSONUnknownType); err1 == nil {
|
if _, err1 := runtime.DefaultCodec.Decode(badJSONUnknownType); err1 == nil {
|
||||||
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
||||||
}
|
}
|
||||||
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ type ContainerManifestList struct {
|
|||||||
Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ContainerManifestList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
|
// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
// Required: This must be a DNS_LABEL. Each volume in a pod must have
|
// Required: This must be a DNS_LABEL. Each volume in a pod must have
|
||||||
@@ -287,6 +289,8 @@ type PodList struct {
|
|||||||
Items []Pod `json:"items" yaml:"items,omitempty"`
|
Items []Pod `json:"items" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*PodList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Pod is a collection of containers, used as either input (create, update) or as output (list, get).
|
// Pod is a collection of containers, used as either input (create, update) or as output (list, get).
|
||||||
type Pod struct {
|
type Pod struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -295,6 +299,8 @@ type Pod struct {
|
|||||||
CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"`
|
CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Pod) IsAnAPIObject() {}
|
||||||
|
|
||||||
// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get).
|
// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get).
|
||||||
type ReplicationControllerState struct {
|
type ReplicationControllerState struct {
|
||||||
Replicas int `json:"replicas" yaml:"replicas"`
|
Replicas int `json:"replicas" yaml:"replicas"`
|
||||||
@@ -308,6 +314,8 @@ type ReplicationControllerList struct {
|
|||||||
Items []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ReplicationControllerList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// ReplicationController represents the configuration of a replication controller.
|
// ReplicationController represents the configuration of a replication controller.
|
||||||
type ReplicationController struct {
|
type ReplicationController struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -315,6 +323,8 @@ type ReplicationController struct {
|
|||||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ReplicationController) IsAnAPIObject() {}
|
||||||
|
|
||||||
// PodTemplate holds the information used for creating pods.
|
// PodTemplate holds the information used for creating pods.
|
||||||
type PodTemplate struct {
|
type PodTemplate struct {
|
||||||
DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
|
DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
|
||||||
@@ -327,6 +337,8 @@ type ServiceList struct {
|
|||||||
Items []Service `json:"items" yaml:"items"`
|
Items []Service `json:"items" yaml:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServiceList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Service is a named abstraction of software service (for example, mysql) consisting of local port
|
// Service is a named abstraction of software service (for example, mysql) consisting of local port
|
||||||
// (for example 3306) that the proxy listens on, and the selector that determines which pods
|
// (for example 3306) that the proxy listens on, and the selector that determines which pods
|
||||||
// will answer requests sent through the proxy.
|
// will answer requests sent through the proxy.
|
||||||
@@ -346,6 +358,8 @@ type Service struct {
|
|||||||
ContainerPort util.IntOrString `json:"containerPort,omitempty" yaml:"containerPort,omitempty"`
|
ContainerPort util.IntOrString `json:"containerPort,omitempty" yaml:"containerPort,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Service) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Endpoints is a collection of endpoints that implement the actual service, for example:
|
// Endpoints is a collection of endpoints that implement the actual service, for example:
|
||||||
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
|
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
|
||||||
type Endpoints struct {
|
type Endpoints struct {
|
||||||
@@ -353,12 +367,16 @@ type Endpoints struct {
|
|||||||
Endpoints []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
|
Endpoints []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Endpoints) IsAnAPIObject() {}
|
||||||
|
|
||||||
// EndpointsList is a list of endpoints.
|
// EndpointsList is a list of endpoints.
|
||||||
type EndpointsList struct {
|
type EndpointsList struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
Items []Endpoints `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []Endpoints `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*EndpointsList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Minion is a worker node in Kubernetenes.
|
// Minion is a worker node in Kubernetenes.
|
||||||
// The name of the minion according to etcd is in JSONBase.ID.
|
// The name of the minion according to etcd is in JSONBase.ID.
|
||||||
type Minion struct {
|
type Minion struct {
|
||||||
@@ -367,12 +385,16 @@ type Minion struct {
|
|||||||
HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
|
HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Minion) IsAnAPIObject() {}
|
||||||
|
|
||||||
// MinionList is a list of minions.
|
// MinionList is a list of minions.
|
||||||
type MinionList struct {
|
type MinionList struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
Items []Minion `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []Minion `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*MinionList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Binding is written by a scheduler to cause a pod to be bound to a host.
|
// Binding is written by a scheduler to cause a pod to be bound to a host.
|
||||||
type Binding struct {
|
type Binding struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -380,6 +402,8 @@ type Binding struct {
|
|||||||
Host string `json:"host" yaml:"host"`
|
Host string `json:"host" yaml:"host"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Binding) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Status is a return value for calls that don't return other objects.
|
// Status is a return value for calls that don't return other objects.
|
||||||
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
||||||
// import both.
|
// import both.
|
||||||
@@ -403,6 +427,8 @@ type Status struct {
|
|||||||
Code int `json:"code,omitempty" yaml:"code,omitempty"`
|
Code int `json:"code,omitempty" yaml:"code,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Status) IsAnAPIObject() {}
|
||||||
|
|
||||||
// StatusDetails is a set of additional properties that MAY be set by the
|
// StatusDetails is a set of additional properties that MAY be set by the
|
||||||
// server to provide additional information about a response. The Reason
|
// server to provide additional information about a response. The Reason
|
||||||
// field of a Status object defines what attributes will be set. Clients
|
// field of a Status object defines what attributes will be set. Clients
|
||||||
@@ -539,12 +565,16 @@ type ServerOp struct {
|
|||||||
JSONBase `yaml:",inline" json:",inline"`
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServerOp) IsAnAPIObject() {}
|
||||||
|
|
||||||
// ServerOpList is a list of operations, as delivered to API clients.
|
// ServerOpList is a list of operations, as delivered to API clients.
|
||||||
type ServerOpList struct {
|
type ServerOpList struct {
|
||||||
JSONBase `yaml:",inline" json:",inline"`
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
Items []ServerOp `yaml:"items,omitempty" json:"items,omitempty"`
|
Items []ServerOp `yaml:"items,omitempty" json:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServerOpList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||||
type WatchEvent struct {
|
type WatchEvent struct {
|
||||||
// The type of the watch event; added, modified, or deleted.
|
// The type of the watch event; added, modified, or deleted.
|
||||||
|
|||||||
@@ -19,22 +19,20 @@ package v1beta1
|
|||||||
import (
|
import (
|
||||||
// Alias this so it can be easily changed when we cut the next version.
|
// Alias this so it can be easily changed when we cut the next version.
|
||||||
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Shortcut for sub-conversions. TODO: This should possibly be refactored
|
runtime.DefaultScheme.AddConversionFuncs(
|
||||||
// such that this convert function is passed to each conversion func.
|
|
||||||
Convert := runtime.Convert
|
|
||||||
runtime.AddConversionFuncs(
|
|
||||||
// EnvVar's Key is deprecated in favor of Name.
|
// EnvVar's Key is deprecated in favor of Name.
|
||||||
func(in *newer.EnvVar, out *EnvVar) error {
|
func(in *newer.EnvVar, out *EnvVar, s conversion.Scope) error {
|
||||||
out.Value = in.Value
|
out.Value = in.Value
|
||||||
out.Key = in.Name
|
out.Key = in.Name
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
func(in *EnvVar, out *newer.EnvVar) error {
|
func(in *EnvVar, out *newer.EnvVar, s conversion.Scope) error {
|
||||||
out.Value = in.Value
|
out.Value = in.Value
|
||||||
if in.Name != "" {
|
if in.Name != "" {
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
@@ -45,7 +43,7 @@ func init() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Path & MountType are deprecated.
|
// Path & MountType are deprecated.
|
||||||
func(in *newer.VolumeMount, out *VolumeMount) error {
|
func(in *newer.VolumeMount, out *VolumeMount, s conversion.Scope) error {
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
out.ReadOnly = in.ReadOnly
|
out.ReadOnly = in.ReadOnly
|
||||||
out.MountPath = in.MountPath
|
out.MountPath = in.MountPath
|
||||||
@@ -53,7 +51,7 @@ func init() {
|
|||||||
out.MountType = "" // MountType is ignored.
|
out.MountType = "" // MountType is ignored.
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
func(in *VolumeMount, out *newer.VolumeMount) error {
|
func(in *VolumeMount, out *newer.VolumeMount, s conversion.Scope) error {
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
out.ReadOnly = in.ReadOnly
|
out.ReadOnly = in.ReadOnly
|
||||||
if in.MountPath == "" {
|
if in.MountPath == "" {
|
||||||
@@ -65,18 +63,18 @@ func init() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// MinionList.Items had a wrong name in v1beta1
|
// MinionList.Items had a wrong name in v1beta1
|
||||||
func(in *newer.MinionList, out *MinionList) error {
|
func(in *newer.MinionList, out *MinionList, s conversion.Scope) error {
|
||||||
Convert(&in.JSONBase, &out.JSONBase)
|
s.Convert(&in.JSONBase, &out.JSONBase, 0)
|
||||||
Convert(&in.Items, &out.Items)
|
s.Convert(&in.Items, &out.Items, 0)
|
||||||
out.Minions = out.Items
|
out.Minions = out.Items
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
func(in *MinionList, out *newer.MinionList) error {
|
func(in *MinionList, out *newer.MinionList, s conversion.Scope) error {
|
||||||
Convert(&in.JSONBase, &out.JSONBase)
|
s.Convert(&in.JSONBase, &out.JSONBase, 0)
|
||||||
if len(in.Items) == 0 {
|
if len(in.Items) == 0 {
|
||||||
Convert(&in.Minions, &out.Items)
|
s.Convert(&in.Minions, &out.Items, 0)
|
||||||
} else {
|
} else {
|
||||||
Convert(&in.Items, &out.Items)
|
s.Convert(&in.Items, &out.Items, 0)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Convert = runtime.Convert
|
var Convert = runtime.DefaultScheme.Convert
|
||||||
|
|
||||||
func TestEnvConversion(t *testing.T) {
|
func TestEnvConversion(t *testing.T) {
|
||||||
nonCanonical := []v1beta1.EnvVar{
|
nonCanonical := []v1beta1.EnvVar{
|
||||||
|
|||||||
@@ -21,21 +21,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.AddKnownTypes("v1beta1",
|
runtime.DefaultScheme.AddKnownTypes("v1beta1",
|
||||||
PodList{},
|
&PodList{},
|
||||||
Pod{},
|
&Pod{},
|
||||||
ReplicationControllerList{},
|
&ReplicationControllerList{},
|
||||||
ReplicationController{},
|
&ReplicationController{},
|
||||||
ServiceList{},
|
&ServiceList{},
|
||||||
Service{},
|
&Service{},
|
||||||
MinionList{},
|
&MinionList{},
|
||||||
Minion{},
|
&Minion{},
|
||||||
Status{},
|
&Status{},
|
||||||
ServerOpList{},
|
&ServerOpList{},
|
||||||
ServerOp{},
|
&ServerOp{},
|
||||||
ContainerManifestList{},
|
&ContainerManifestList{},
|
||||||
Endpoints{},
|
&Endpoints{},
|
||||||
EndpointsList{},
|
&EndpointsList{},
|
||||||
Binding{},
|
&Binding{},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ type ContainerManifestList struct {
|
|||||||
Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ContainerManifestList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
|
// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
// Required: This must be a DNS_LABEL. Each volume in a pod must have
|
// Required: This must be a DNS_LABEL. Each volume in a pod must have
|
||||||
@@ -243,6 +245,8 @@ type JSONBase struct {
|
|||||||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*JSONBase) IsAnAPIObject() {}
|
||||||
|
|
||||||
// PodStatus represents a status of a pod.
|
// PodStatus represents a status of a pod.
|
||||||
type PodStatus string
|
type PodStatus string
|
||||||
|
|
||||||
@@ -298,6 +302,8 @@ type PodList struct {
|
|||||||
Items []Pod `json:"items" yaml:"items,omitempty"`
|
Items []Pod `json:"items" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*PodList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Pod is a collection of containers, used as either input (create, update) or as output (list, get).
|
// Pod is a collection of containers, used as either input (create, update) or as output (list, get).
|
||||||
type Pod struct {
|
type Pod struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -306,6 +312,8 @@ type Pod struct {
|
|||||||
CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"`
|
CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Pod) IsAnAPIObject() {}
|
||||||
|
|
||||||
// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get).
|
// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get).
|
||||||
type ReplicationControllerState struct {
|
type ReplicationControllerState struct {
|
||||||
Replicas int `json:"replicas" yaml:"replicas"`
|
Replicas int `json:"replicas" yaml:"replicas"`
|
||||||
@@ -319,6 +327,8 @@ type ReplicationControllerList struct {
|
|||||||
Items []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ReplicationControllerList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// ReplicationController represents the configuration of a replication controller.
|
// ReplicationController represents the configuration of a replication controller.
|
||||||
type ReplicationController struct {
|
type ReplicationController struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -326,6 +336,8 @@ type ReplicationController struct {
|
|||||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ReplicationController) IsAnAPIObject() {}
|
||||||
|
|
||||||
// PodTemplate holds the information used for creating pods.
|
// PodTemplate holds the information used for creating pods.
|
||||||
type PodTemplate struct {
|
type PodTemplate struct {
|
||||||
DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
|
DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
|
||||||
@@ -338,6 +350,8 @@ type ServiceList struct {
|
|||||||
Items []Service `json:"items" yaml:"items"`
|
Items []Service `json:"items" yaml:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServiceList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Service is a named abstraction of software service (for example, mysql) consisting of local port
|
// Service is a named abstraction of software service (for example, mysql) consisting of local port
|
||||||
// (for example 3306) that the proxy listens on, and the selector that determines which pods
|
// (for example 3306) that the proxy listens on, and the selector that determines which pods
|
||||||
// will answer requests sent through the proxy.
|
// will answer requests sent through the proxy.
|
||||||
@@ -357,6 +371,8 @@ type Service struct {
|
|||||||
ContainerPort util.IntOrString `json:"containerPort,omitempty" yaml:"containerPort,omitempty"`
|
ContainerPort util.IntOrString `json:"containerPort,omitempty" yaml:"containerPort,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Service) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Endpoints is a collection of endpoints that implement the actual service, for example:
|
// Endpoints is a collection of endpoints that implement the actual service, for example:
|
||||||
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
|
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
|
||||||
type Endpoints struct {
|
type Endpoints struct {
|
||||||
@@ -364,12 +380,16 @@ type Endpoints struct {
|
|||||||
Endpoints []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
|
Endpoints []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Endpoints) IsAnAPIObject() {}
|
||||||
|
|
||||||
// EndpointsList is a list of endpoints.
|
// EndpointsList is a list of endpoints.
|
||||||
type EndpointsList struct {
|
type EndpointsList struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
Items []Endpoints `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []Endpoints `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*EndpointsList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Minion is a worker node in Kubernetenes.
|
// Minion is a worker node in Kubernetenes.
|
||||||
// The name of the minion according to etcd is in JSONBase.ID.
|
// The name of the minion according to etcd is in JSONBase.ID.
|
||||||
type Minion struct {
|
type Minion struct {
|
||||||
@@ -378,6 +398,8 @@ type Minion struct {
|
|||||||
HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
|
HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Minion) IsAnAPIObject() {}
|
||||||
|
|
||||||
// MinionList is a list of minions.
|
// MinionList is a list of minions.
|
||||||
type MinionList struct {
|
type MinionList struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -387,6 +409,8 @@ type MinionList struct {
|
|||||||
Items []Minion `json:"items,omitempty" yaml:"items,omitempty"`
|
Items []Minion `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*MinionList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Binding is written by a scheduler to cause a pod to be bound to a host.
|
// Binding is written by a scheduler to cause a pod to be bound to a host.
|
||||||
type Binding struct {
|
type Binding struct {
|
||||||
JSONBase `json:",inline" yaml:",inline"`
|
JSONBase `json:",inline" yaml:",inline"`
|
||||||
@@ -394,6 +418,8 @@ type Binding struct {
|
|||||||
Host string `json:"host" yaml:"host"`
|
Host string `json:"host" yaml:"host"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Binding) IsAnAPIObject() {}
|
||||||
|
|
||||||
// Status is a return value for calls that don't return other objects.
|
// Status is a return value for calls that don't return other objects.
|
||||||
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
||||||
// import both.
|
// import both.
|
||||||
@@ -417,6 +443,8 @@ type Status struct {
|
|||||||
Code int `json:"code,omitempty" yaml:"code,omitempty"`
|
Code int `json:"code,omitempty" yaml:"code,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Status) IsAnAPIObject() {}
|
||||||
|
|
||||||
// StatusDetails is a set of additional properties that MAY be set by the
|
// StatusDetails is a set of additional properties that MAY be set by the
|
||||||
// server to provide additional information about a response. The Reason
|
// server to provide additional information about a response. The Reason
|
||||||
// field of a Status object defines what attributes will be set. Clients
|
// field of a Status object defines what attributes will be set. Clients
|
||||||
@@ -540,12 +568,16 @@ type ServerOp struct {
|
|||||||
JSONBase `yaml:",inline" json:",inline"`
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServerOp) IsAnAPIObject() {}
|
||||||
|
|
||||||
// ServerOpList is a list of operations, as delivered to API clients.
|
// ServerOpList is a list of operations, as delivered to API clients.
|
||||||
type ServerOpList struct {
|
type ServerOpList struct {
|
||||||
JSONBase `yaml:",inline" json:",inline"`
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
Items []ServerOp `yaml:"items,omitempty" json:"items,omitempty"`
|
Items []ServerOp `yaml:"items,omitempty" json:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServerOpList) IsAnAPIObject() {}
|
||||||
|
|
||||||
// WatchEvent objects are streamed from the api server in response to a watch request.
|
// WatchEvent objects are streamed from the api server in response to a watch request.
|
||||||
type WatchEvent struct {
|
type WatchEvent struct {
|
||||||
// The type of the watch event; added, modified, or deleted.
|
// The type of the watch event; added, modified, or deleted.
|
||||||
|
|||||||
@@ -27,17 +27,11 @@ import (
|
|||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Codec defines methods for serializing and deserializing API objects.
|
|
||||||
type Codec interface {
|
|
||||||
Encode(obj interface{}) (data []byte, err error)
|
|
||||||
Decode(data []byte) (interface{}, error)
|
|
||||||
DecodeInto(data []byte, obj interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// mux is an object that can register http handlers.
|
// mux is an object that can register http handlers.
|
||||||
type mux interface {
|
type mux interface {
|
||||||
Handle(pattern string, handler http.Handler)
|
Handle(pattern string, handler http.Handler)
|
||||||
@@ -53,7 +47,7 @@ type defaultAPIServer struct {
|
|||||||
// Handle returns a Handler function that expose the provided storage interfaces
|
// Handle returns a Handler function that expose the provided storage interfaces
|
||||||
// as RESTful resources at prefix, serialized by codec, and also includes the support
|
// as RESTful resources at prefix, serialized by codec, and also includes the support
|
||||||
// http resources.
|
// http resources.
|
||||||
func Handle(storage map[string]RESTStorage, codec Codec, prefix string) http.Handler {
|
func Handle(storage map[string]RESTStorage, codec runtime.Codec, prefix string) http.Handler {
|
||||||
group := NewAPIGroup(storage, codec)
|
group := NewAPIGroup(storage, codec)
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@@ -78,7 +72,7 @@ type APIGroup struct {
|
|||||||
// This is a helper method for registering multiple sets of REST handlers under different
|
// This is a helper method for registering multiple sets of REST handlers under different
|
||||||
// prefixes onto a server.
|
// prefixes onto a server.
|
||||||
// TODO: add multitype codec serialization
|
// TODO: add multitype codec serialization
|
||||||
func NewAPIGroup(storage map[string]RESTStorage, codec Codec) *APIGroup {
|
func NewAPIGroup(storage map[string]RESTStorage, codec runtime.Codec) *APIGroup {
|
||||||
return &APIGroup{RESTHandler{
|
return &APIGroup{RESTHandler{
|
||||||
storage: storage,
|
storage: storage,
|
||||||
codec: codec,
|
codec: codec,
|
||||||
@@ -147,7 +141,7 @@ func handleVersion(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writeJSON renders an object as JSON to the response.
|
// writeJSON renders an object as JSON to the response.
|
||||||
func writeJSON(statusCode int, codec Codec, object interface{}, w http.ResponseWriter) {
|
func writeJSON(statusCode int, codec runtime.Codec, object runtime.Object, w http.ResponseWriter) {
|
||||||
output, err := codec.Encode(object)
|
output, err := codec.Encode(object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorJSON(err, codec, w)
|
errorJSON(err, codec, w)
|
||||||
@@ -159,7 +153,7 @@ func writeJSON(statusCode int, codec Codec, object interface{}, w http.ResponseW
|
|||||||
}
|
}
|
||||||
|
|
||||||
// errorJSON renders an error to the response.
|
// errorJSON renders an error to the response.
|
||||||
func errorJSON(err error, codec Codec, w http.ResponseWriter) {
|
func errorJSON(err error, codec runtime.Codec, w http.ResponseWriter) {
|
||||||
status := errToAPIStatus(err)
|
status := errToAPIStatus(err)
|
||||||
writeJSON(status.Code, codec, status, w)
|
writeJSON(status.Code, codec, status, w)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,15 +38,15 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convert(obj interface{}) (interface{}, error) {
|
func convert(obj runtime.Object) (runtime.Object, error) {
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var codec = runtime.Codec
|
var codec = runtime.DefaultCodec
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.AddKnownTypes("", Simple{}, SimpleList{})
|
runtime.DefaultScheme.AddKnownTypes("", &Simple{}, &SimpleList{})
|
||||||
runtime.AddKnownTypes("v1beta1", Simple{}, SimpleList{})
|
runtime.DefaultScheme.AddKnownTypes("v1beta1", &Simple{}, &SimpleList{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type Simple struct {
|
type Simple struct {
|
||||||
@@ -54,11 +54,15 @@ type Simple struct {
|
|||||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Simple) IsAnAPIObject() {}
|
||||||
|
|
||||||
type SimpleList struct {
|
type SimpleList struct {
|
||||||
api.JSONBase `yaml:",inline" json:",inline"`
|
api.JSONBase `yaml:",inline" json:",inline"`
|
||||||
Items []Simple `yaml:"items,omitempty" json:"items,omitempty"`
|
Items []Simple `yaml:"items,omitempty" json:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*SimpleList) IsAnAPIObject() {}
|
||||||
|
|
||||||
type SimpleRESTStorage struct {
|
type SimpleRESTStorage struct {
|
||||||
errors map[string]error
|
errors map[string]error
|
||||||
list []Simple
|
list []Simple
|
||||||
@@ -78,43 +82,43 @@ type SimpleRESTStorage struct {
|
|||||||
|
|
||||||
// If non-nil, called inside the WorkFunc when answering update, delete, create.
|
// If non-nil, called inside the WorkFunc when answering update, delete, create.
|
||||||
// obj receives the original input to the update, delete, or create call.
|
// obj receives the original input to the update, delete, or create call.
|
||||||
injectedFunction func(obj interface{}) (returnObj interface{}, err error)
|
injectedFunction func(obj runtime.Object) (returnObj runtime.Object, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *SimpleRESTStorage) List(labels.Selector) (interface{}, error) {
|
func (storage *SimpleRESTStorage) List(labels.Selector) (runtime.Object, error) {
|
||||||
result := &SimpleList{
|
result := &SimpleList{
|
||||||
Items: storage.list,
|
Items: storage.list,
|
||||||
}
|
}
|
||||||
return result, storage.errors["list"]
|
return result, storage.errors["list"]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *SimpleRESTStorage) Get(id string) (interface{}, error) {
|
func (storage *SimpleRESTStorage) Get(id string) (runtime.Object, error) {
|
||||||
return storage.item, storage.errors["get"]
|
return runtime.DefaultScheme.CopyOrDie(&storage.item), storage.errors["get"]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *SimpleRESTStorage) Delete(id string) (<-chan interface{}, error) {
|
func (storage *SimpleRESTStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
storage.deleted = id
|
storage.deleted = id
|
||||||
if err := storage.errors["delete"]; err != nil {
|
if err := storage.errors["delete"]; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return MakeAsync(func() (interface{}, error) {
|
return MakeAsync(func() (runtime.Object, error) {
|
||||||
if storage.injectedFunction != nil {
|
if storage.injectedFunction != nil {
|
||||||
return storage.injectedFunction(id)
|
return storage.injectedFunction(&Simple{JSONBase: api.JSONBase{ID: id}})
|
||||||
}
|
}
|
||||||
return &api.Status{Status: api.StatusSuccess}, nil
|
return &api.Status{Status: api.StatusSuccess}, nil
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *SimpleRESTStorage) New() interface{} {
|
func (storage *SimpleRESTStorage) New() runtime.Object {
|
||||||
return &Simple{}
|
return &Simple{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *SimpleRESTStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (storage *SimpleRESTStorage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
storage.created = obj.(*Simple)
|
storage.created = obj.(*Simple)
|
||||||
if err := storage.errors["create"]; err != nil {
|
if err := storage.errors["create"]; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return MakeAsync(func() (interface{}, error) {
|
return MakeAsync(func() (runtime.Object, error) {
|
||||||
if storage.injectedFunction != nil {
|
if storage.injectedFunction != nil {
|
||||||
return storage.injectedFunction(obj)
|
return storage.injectedFunction(obj)
|
||||||
}
|
}
|
||||||
@@ -122,12 +126,12 @@ func (storage *SimpleRESTStorage) Create(obj interface{}) (<-chan interface{}, e
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *SimpleRESTStorage) Update(obj interface{}) (<-chan interface{}, error) {
|
func (storage *SimpleRESTStorage) Update(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
storage.updated = obj.(*Simple)
|
storage.updated = obj.(*Simple)
|
||||||
if err := storage.errors["update"]; err != nil {
|
if err := storage.errors["update"]; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return MakeAsync(func() (interface{}, error) {
|
return MakeAsync(func() (runtime.Object, error) {
|
||||||
if storage.injectedFunction != nil {
|
if storage.injectedFunction != nil {
|
||||||
return storage.injectedFunction(obj)
|
return storage.injectedFunction(obj)
|
||||||
}
|
}
|
||||||
@@ -156,7 +160,7 @@ func (storage *SimpleRESTStorage) ResourceLocation(id string) (string, error) {
|
|||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractBody(response *http.Response, object interface{}) (string, error) {
|
func extractBody(response *http.Response, object runtime.Object) (string, error) {
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
body, err := ioutil.ReadAll(response.Body)
|
body, err := ioutil.ReadAll(response.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -398,7 +402,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
handler := Handle(storage, codec, "/prefix/version")
|
handler := Handle(storage, codec, "/prefix/version")
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
|
|
||||||
item := Simple{
|
item := &Simple{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
}
|
}
|
||||||
body, err := codec.Encode(item)
|
body, err := codec.Encode(item)
|
||||||
@@ -428,7 +432,7 @@ func TestUpdateMissing(t *testing.T) {
|
|||||||
handler := Handle(storage, codec, "/prefix/version")
|
handler := Handle(storage, codec, "/prefix/version")
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
|
|
||||||
item := Simple{
|
item := &Simple{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
}
|
}
|
||||||
body, err := codec.Encode(item)
|
body, err := codec.Encode(item)
|
||||||
@@ -457,7 +461,7 @@ func TestCreate(t *testing.T) {
|
|||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
|
|
||||||
simple := Simple{
|
simple := &Simple{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
}
|
}
|
||||||
data, _ := codec.Encode(simple)
|
data, _ := codec.Encode(simple)
|
||||||
@@ -497,7 +501,7 @@ func TestCreateNotFound(t *testing.T) {
|
|||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
|
|
||||||
simple := Simple{Name: "foo"}
|
simple := &Simple{Name: "foo"}
|
||||||
data, _ := codec.Encode(simple)
|
data, _ := codec.Encode(simple)
|
||||||
request, err := http.NewRequest("POST", server.URL+"/prefix/version/simple", bytes.NewBuffer(data))
|
request, err := http.NewRequest("POST", server.URL+"/prefix/version/simple", bytes.NewBuffer(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -528,7 +532,7 @@ func TestParseTimeout(t *testing.T) {
|
|||||||
|
|
||||||
func TestSyncCreate(t *testing.T) {
|
func TestSyncCreate(t *testing.T) {
|
||||||
storage := SimpleRESTStorage{
|
storage := SimpleRESTStorage{
|
||||||
injectedFunction: func(obj interface{}) (interface{}, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
time.Sleep(5 * time.Millisecond)
|
time.Sleep(5 * time.Millisecond)
|
||||||
return obj, nil
|
return obj, nil
|
||||||
},
|
},
|
||||||
@@ -539,7 +543,7 @@ func TestSyncCreate(t *testing.T) {
|
|||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
|
|
||||||
simple := Simple{
|
simple := &Simple{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
}
|
}
|
||||||
data, _ := codec.Encode(simple)
|
data, _ := codec.Encode(simple)
|
||||||
@@ -566,7 +570,7 @@ func TestSyncCreate(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(itemOut, simple) {
|
if !reflect.DeepEqual(&itemOut, simple) {
|
||||||
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simple, string(body))
|
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simple, string(body))
|
||||||
}
|
}
|
||||||
if response.StatusCode != http.StatusOK {
|
if response.StatusCode != http.StatusOK {
|
||||||
@@ -600,7 +604,7 @@ func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *a
|
|||||||
|
|
||||||
func TestAsyncDelayReturnsError(t *testing.T) {
|
func TestAsyncDelayReturnsError(t *testing.T) {
|
||||||
storage := SimpleRESTStorage{
|
storage := SimpleRESTStorage{
|
||||||
injectedFunction: func(obj interface{}) (interface{}, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
return nil, apierrs.NewAlreadyExists("foo", "bar")
|
return nil, apierrs.NewAlreadyExists("foo", "bar")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -617,7 +621,7 @@ func TestAsyncDelayReturnsError(t *testing.T) {
|
|||||||
func TestAsyncCreateError(t *testing.T) {
|
func TestAsyncCreateError(t *testing.T) {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
storage := SimpleRESTStorage{
|
storage := SimpleRESTStorage{
|
||||||
injectedFunction: func(obj interface{}) (interface{}, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
<-ch
|
<-ch
|
||||||
return nil, apierrs.NewAlreadyExists("foo", "bar")
|
return nil, apierrs.NewAlreadyExists("foo", "bar")
|
||||||
},
|
},
|
||||||
@@ -626,7 +630,7 @@ func TestAsyncCreateError(t *testing.T) {
|
|||||||
handler.(*defaultAPIServer).group.handler.asyncOpWait = 0
|
handler.(*defaultAPIServer).group.handler.asyncOpWait = 0
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
|
|
||||||
simple := Simple{Name: "foo"}
|
simple := &Simple{Name: "foo"}
|
||||||
data, _ := codec.Encode(simple)
|
data, _ := codec.Encode(simple)
|
||||||
|
|
||||||
status := expectApiStatus(t, "POST", fmt.Sprintf("%s/prefix/version/foo", server.URL), data, http.StatusAccepted)
|
status := expectApiStatus(t, "POST", fmt.Sprintf("%s/prefix/version/foo", server.URL), data, http.StatusAccepted)
|
||||||
@@ -662,18 +666,21 @@ func TestAsyncCreateError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UnregisteredAPIObject struct {
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UnregisteredAPIObject) IsAnAPIObject() {}
|
||||||
|
|
||||||
func TestWriteJSONDecodeError(t *testing.T) {
|
func TestWriteJSONDecodeError(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
type T struct {
|
writeJSON(http.StatusOK, runtime.DefaultCodec, &UnregisteredAPIObject{"Undecodable"}, w)
|
||||||
Value string
|
|
||||||
}
|
|
||||||
writeJSON(http.StatusOK, runtime.Codec, &T{"Undecodable"}, w)
|
|
||||||
}))
|
}))
|
||||||
status := expectApiStatus(t, "GET", server.URL, nil, http.StatusInternalServerError)
|
status := expectApiStatus(t, "GET", server.URL, nil, http.StatusInternalServerError)
|
||||||
if status.Reason != api.StatusReasonUnknown {
|
if status.Reason != api.StatusReasonUnknown {
|
||||||
t.Errorf("unexpected reason %#v", status)
|
t.Errorf("unexpected reason %#v", status)
|
||||||
}
|
}
|
||||||
if !strings.Contains(status.Message, "type apiserver.T is not registered") {
|
if !strings.Contains(status.Message, "type apiserver.UnregisteredAPIObject is not registered") {
|
||||||
t.Errorf("unexpected message %#v", status)
|
t.Errorf("unexpected message %#v", status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -705,7 +712,7 @@ func TestSyncCreateTimeout(t *testing.T) {
|
|||||||
testOver := make(chan struct{})
|
testOver := make(chan struct{})
|
||||||
defer close(testOver)
|
defer close(testOver)
|
||||||
storage := SimpleRESTStorage{
|
storage := SimpleRESTStorage{
|
||||||
injectedFunction: func(obj interface{}) (interface{}, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
// Eliminate flakes by ensuring the create operation takes longer than this test.
|
// Eliminate flakes by ensuring the create operation takes longer than this test.
|
||||||
<-testOver
|
<-testOver
|
||||||
return obj, nil
|
return obj, nil
|
||||||
@@ -716,7 +723,7 @@ func TestSyncCreateTimeout(t *testing.T) {
|
|||||||
}, codec, "/prefix/version")
|
}, codec, "/prefix/version")
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
|
|
||||||
simple := Simple{Name: "foo"}
|
simple := &Simple{Name: "foo"}
|
||||||
data, _ := codec.Encode(simple)
|
data, _ := codec.Encode(simple)
|
||||||
itemOut := expectApiStatus(t, "POST", server.URL+"/prefix/version/foo?sync=true&timeout=4ms", data, http.StatusAccepted)
|
itemOut := expectApiStatus(t, "POST", server.URL+"/prefix/version/foo?sync=true&timeout=4ms", data, http.StatusAccepted)
|
||||||
if itemOut.Status != api.StatusWorking || itemOut.Details == nil || itemOut.Details.ID == "" {
|
if itemOut.Status != api.StatusWorking || itemOut.Details == nil || itemOut.Details.ID == "" {
|
||||||
|
|||||||
@@ -17,18 +17,19 @@ limitations under the License.
|
|||||||
package apiserver
|
package apiserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WorkFunc is used to perform any time consuming work for an api call, after
|
// WorkFunc is used to perform any time consuming work for an api call, after
|
||||||
// the input has been validated. Pass one of these to MakeAsync to create an
|
// the input has been validated. Pass one of these to MakeAsync to create an
|
||||||
// appropriate return value for the Update, Delete, and Create methods.
|
// appropriate return value for the Update, Delete, and Create methods.
|
||||||
type WorkFunc func() (result interface{}, err error)
|
type WorkFunc func() (result runtime.Object, err error)
|
||||||
|
|
||||||
// MakeAsync takes a function and executes it, delivering the result in the way required
|
// MakeAsync takes a function and executes it, delivering the result in the way required
|
||||||
// by RESTStorage's Update, Delete, and Create methods.
|
// by RESTStorage's Update, Delete, and Create methods.
|
||||||
func MakeAsync(fn WorkFunc) <-chan interface{} {
|
func MakeAsync(fn WorkFunc) <-chan runtime.Object {
|
||||||
channel := make(chan interface{})
|
channel := make(chan runtime.Object)
|
||||||
go func() {
|
go func() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
obj, err := fn()
|
obj, err := fn()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package apiserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,25 +26,25 @@ import (
|
|||||||
// Resources which are exported to the RESTful API of apiserver need to implement this interface.
|
// Resources which are exported to the RESTful API of apiserver need to implement this interface.
|
||||||
type RESTStorage interface {
|
type RESTStorage interface {
|
||||||
// New returns an empty object that can be used with Create and Update after request data has been put into it.
|
// New returns an empty object that can be used with Create and Update after request data has been put into it.
|
||||||
// This object must be a pointer type for use with Codec.DecodeInto([]byte, interface{})
|
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
|
||||||
New() interface{}
|
New() runtime.Object
|
||||||
|
|
||||||
// List selects resources in the storage which match to the selector.
|
// List selects resources in the storage which match to the selector.
|
||||||
// TODO: add field selector in addition to label selector.
|
// TODO: add field selector in addition to label selector.
|
||||||
List(labels.Selector) (interface{}, error)
|
List(labels.Selector) (runtime.Object, error)
|
||||||
|
|
||||||
// Get finds a resource in the storage by id and returns it.
|
// Get finds a resource in the storage by id and returns it.
|
||||||
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
|
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
|
||||||
// returned error value err when the specified resource is not found.
|
// returned error value err when the specified resource is not found.
|
||||||
Get(id string) (interface{}, error)
|
Get(id string) (runtime.Object, error)
|
||||||
|
|
||||||
// Delete finds a resource in the storage and deletes it.
|
// Delete finds a resource in the storage and deletes it.
|
||||||
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
|
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
|
||||||
// returned error value err when the specified resource is not found.
|
// returned error value err when the specified resource is not found.
|
||||||
Delete(id string) (<-chan interface{}, error)
|
Delete(id string) (<-chan runtime.Object, error)
|
||||||
|
|
||||||
Create(interface{}) (<-chan interface{}, error)
|
Create(runtime.Object) (<-chan runtime.Object, error)
|
||||||
Update(interface{}) (<-chan interface{}, error)
|
Update(runtime.Object) (<-chan runtime.Object, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceWatcher should be implemented by all RESTStorage objects that
|
// ResourceWatcher should be implemented by all RESTStorage objects that
|
||||||
|
|||||||
@@ -25,12 +25,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OperationHandler struct {
|
type OperationHandler struct {
|
||||||
ops *Operations
|
ops *Operations
|
||||||
codec Codec
|
codec runtime.Codec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *OperationHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (h *OperationHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
@@ -63,8 +64,8 @@ func (h *OperationHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
// Operation represents an ongoing action which the server is performing.
|
// Operation represents an ongoing action which the server is performing.
|
||||||
type Operation struct {
|
type Operation struct {
|
||||||
ID string
|
ID string
|
||||||
result interface{}
|
result runtime.Object
|
||||||
awaiting <-chan interface{}
|
awaiting <-chan runtime.Object
|
||||||
finished *time.Time
|
finished *time.Time
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
notify chan struct{}
|
notify chan struct{}
|
||||||
@@ -90,7 +91,7 @@ func NewOperations() *Operations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOperation adds a new operation. It is lock-free.
|
// NewOperation adds a new operation. It is lock-free.
|
||||||
func (ops *Operations) NewOperation(from <-chan interface{}) *Operation {
|
func (ops *Operations) NewOperation(from <-chan runtime.Object) *Operation {
|
||||||
id := atomic.AddInt64(&ops.lastID, 1)
|
id := atomic.AddInt64(&ops.lastID, 1)
|
||||||
op := &Operation{
|
op := &Operation{
|
||||||
ID: strconv.FormatInt(id, 10),
|
ID: strconv.FormatInt(id, 10),
|
||||||
@@ -110,7 +111,7 @@ func (ops *Operations) insert(op *Operation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List lists operations for an API client.
|
// List lists operations for an API client.
|
||||||
func (ops *Operations) List() api.ServerOpList {
|
func (ops *Operations) List() *api.ServerOpList {
|
||||||
ops.lock.Lock()
|
ops.lock.Lock()
|
||||||
defer ops.lock.Unlock()
|
defer ops.lock.Unlock()
|
||||||
|
|
||||||
@@ -119,7 +120,7 @@ func (ops *Operations) List() api.ServerOpList {
|
|||||||
ids = append(ids, id)
|
ids = append(ids, id)
|
||||||
}
|
}
|
||||||
sort.StringSlice(ids).Sort()
|
sort.StringSlice(ids).Sort()
|
||||||
ol := api.ServerOpList{}
|
ol := &api.ServerOpList{}
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
ol.Items = append(ol.Items, api.ServerOp{JSONBase: api.JSONBase{ID: id}})
|
ol.Items = append(ol.Items, api.ServerOp{JSONBase: api.JSONBase{ID: id}})
|
||||||
}
|
}
|
||||||
@@ -185,7 +186,7 @@ func (op *Operation) expired(limitTime time.Time) bool {
|
|||||||
|
|
||||||
// StatusOrResult returns status information or the result of the operation if it is complete,
|
// StatusOrResult returns status information or the result of the operation if it is complete,
|
||||||
// with a bool indicating true in the latter case.
|
// with a bool indicating true in the latter case.
|
||||||
func (op *Operation) StatusOrResult() (description interface{}, finished bool) {
|
func (op *Operation) StatusOrResult() (description runtime.Object, finished bool) {
|
||||||
op.lock.Lock()
|
op.lock.Lock()
|
||||||
defer op.lock.Unlock()
|
defer op.lock.Unlock()
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,13 @@ import (
|
|||||||
// TODO: remove dependency on api, apiserver should be generic
|
// TODO: remove dependency on api, apiserver should be generic
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOperation(t *testing.T) {
|
func TestOperation(t *testing.T) {
|
||||||
ops := NewOperations()
|
ops := NewOperations()
|
||||||
|
|
||||||
c := make(chan interface{})
|
c := make(chan runtime.Object)
|
||||||
op := ops.NewOperation(c)
|
op := ops.NewOperation(c)
|
||||||
// Allow context switch, so that op's ID can get added to the map and Get will work.
|
// Allow context switch, so that op's ID can get added to the map and Get will work.
|
||||||
// This is just so we can test Get. Ordinary users have no need to call Get immediately
|
// This is just so we can test Get. Ordinary users have no need to call Get immediately
|
||||||
@@ -41,7 +42,7 @@ func TestOperation(t *testing.T) {
|
|||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
c <- "All done"
|
c <- &Simple{JSONBase: api.JSONBase{ID: "All done"}}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if op.expired(time.Now().Add(-time.Minute)) {
|
if op.expired(time.Now().Add(-time.Minute)) {
|
||||||
@@ -89,7 +90,7 @@ func TestOperation(t *testing.T) {
|
|||||||
t.Errorf("expire failed to remove the operation %#v", ops)
|
t.Errorf("expire failed to remove the operation %#v", ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
if op.result.(string) != "All done" {
|
if op.result.(*Simple).ID != "All done" {
|
||||||
t.Errorf("Got unexpected result: %#v", op.result)
|
t.Errorf("Got unexpected result: %#v", op.result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +99,7 @@ func TestOperationsList(t *testing.T) {
|
|||||||
testOver := make(chan struct{})
|
testOver := make(chan struct{})
|
||||||
defer close(testOver)
|
defer close(testOver)
|
||||||
simpleStorage := &SimpleRESTStorage{
|
simpleStorage := &SimpleRESTStorage{
|
||||||
injectedFunction: func(obj interface{}) (interface{}, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
// Eliminate flakes by ensuring the create operation takes longer than this test.
|
// Eliminate flakes by ensuring the create operation takes longer than this test.
|
||||||
<-testOver
|
<-testOver
|
||||||
return obj, nil
|
return obj, nil
|
||||||
@@ -111,7 +112,7 @@ func TestOperationsList(t *testing.T) {
|
|||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
|
|
||||||
simple := Simple{
|
simple := &Simple{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
}
|
}
|
||||||
data, err := codec.Encode(simple)
|
data, err := codec.Encode(simple)
|
||||||
@@ -154,7 +155,7 @@ func TestOpGet(t *testing.T) {
|
|||||||
testOver := make(chan struct{})
|
testOver := make(chan struct{})
|
||||||
defer close(testOver)
|
defer close(testOver)
|
||||||
simpleStorage := &SimpleRESTStorage{
|
simpleStorage := &SimpleRESTStorage{
|
||||||
injectedFunction: func(obj interface{}) (interface{}, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
// Eliminate flakes by ensuring the create operation takes longer than this test.
|
// Eliminate flakes by ensuring the create operation takes longer than this test.
|
||||||
<-testOver
|
<-testOver
|
||||||
return obj, nil
|
return obj, nil
|
||||||
@@ -167,7 +168,7 @@ func TestOpGet(t *testing.T) {
|
|||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
|
|
||||||
simple := Simple{
|
simple := &Simple{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
}
|
}
|
||||||
data, err := codec.Encode(simple)
|
data, err := codec.Encode(simple)
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RedirectHandler struct {
|
type RedirectHandler struct {
|
||||||
storage map[string]RESTStorage
|
storage map[string]RESTStorage
|
||||||
codec Codec
|
codec runtime.Codec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedirectHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (r *RedirectHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|||||||
@@ -23,11 +23,12 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RESTHandler struct {
|
type RESTHandler struct {
|
||||||
storage map[string]RESTStorage
|
storage map[string]RESTStorage
|
||||||
codec Codec
|
codec runtime.Codec
|
||||||
ops *Operations
|
ops *Operations
|
||||||
asyncOpWait time.Duration
|
asyncOpWait time.Duration
|
||||||
}
|
}
|
||||||
@@ -158,7 +159,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createOperation creates an operation to process a channel response.
|
// createOperation creates an operation to process a channel response.
|
||||||
func (h *RESTHandler) createOperation(out <-chan interface{}, sync bool, timeout time.Duration) *Operation {
|
func (h *RESTHandler) createOperation(out <-chan runtime.Object, sync bool, timeout time.Duration) *Operation {
|
||||||
op := h.ops.NewOperation(out)
|
op := h.ops.NewOperation(out)
|
||||||
if sync {
|
if sync {
|
||||||
op.WaitFor(timeout)
|
op.WaitFor(timeout)
|
||||||
@@ -175,11 +176,6 @@ func (h *RESTHandler) finishReq(op *Operation, w http.ResponseWriter) {
|
|||||||
if complete {
|
if complete {
|
||||||
status := http.StatusOK
|
status := http.StatusOK
|
||||||
switch stat := obj.(type) {
|
switch stat := obj.(type) {
|
||||||
case api.Status:
|
|
||||||
httplog.LogOf(w).Addf("programmer error: use *api.Status as a result, not api.Status.")
|
|
||||||
if stat.Code != 0 {
|
|
||||||
status = stat.Code
|
|
||||||
}
|
|
||||||
case *api.Status:
|
case *api.Status:
|
||||||
if stat.Code != 0 {
|
if stat.Code != 0 {
|
||||||
status = stat.Code
|
status = stat.Code
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
|
|
||||||
type WatchHandler struct {
|
type WatchHandler struct {
|
||||||
storage map[string]RESTStorage
|
storage map[string]RESTStorage
|
||||||
codec Codec
|
codec runtime.Codec
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWatchParams(query url.Values) (label, field labels.Selector, resourceVersion uint64) {
|
func getWatchParams(query url.Values) (label, field labels.Selector, resourceVersion uint64) {
|
||||||
|
|||||||
@@ -26,12 +26,13 @@ import (
|
|||||||
|
|
||||||
"code.google.com/p/go.net/websocket"
|
"code.google.com/p/go.net/websocket"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
var watchTestTable = []struct {
|
var watchTestTable = []struct {
|
||||||
t watch.EventType
|
t watch.EventType
|
||||||
obj interface{}
|
obj runtime.Object
|
||||||
}{
|
}{
|
||||||
{watch.Added, &Simple{Name: "A Name"}},
|
{watch.Added, &Simple{Name: "A Name"}},
|
||||||
{watch.Modified, &Simple{Name: "Another Name"}},
|
{watch.Modified, &Simple{Name: "Another Name"}},
|
||||||
@@ -56,7 +57,7 @@ func TestWatchWebsocket(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
try := func(action watch.EventType, object interface{}) {
|
try := func(action watch.EventType, object runtime.Object) {
|
||||||
// Send
|
// Send
|
||||||
simpleStorage.fakeWatch.Action(action, object)
|
simpleStorage.fakeWatch.Action(action, object)
|
||||||
// Test receive
|
// Test receive
|
||||||
@@ -113,7 +114,7 @@ func TestWatchHTTP(t *testing.T) {
|
|||||||
|
|
||||||
decoder := json.NewDecoder(response.Body)
|
decoder := json.NewDecoder(response.Body)
|
||||||
|
|
||||||
try := func(action watch.EventType, object interface{}) {
|
try := func(action watch.EventType, object runtime.Object) {
|
||||||
// Send
|
// Send
|
||||||
simpleStorage.fakeWatch.Action(action, object)
|
simpleStorage.fakeWatch.Action(action, object)
|
||||||
// Test receive
|
// Test receive
|
||||||
|
|||||||
@@ -46,36 +46,36 @@ type Interface interface {
|
|||||||
|
|
||||||
// PodInterface has methods to work with Pod resources.
|
// PodInterface has methods to work with Pod resources.
|
||||||
type PodInterface interface {
|
type PodInterface interface {
|
||||||
ListPods(selector labels.Selector) (api.PodList, error)
|
ListPods(selector labels.Selector) (*api.PodList, error)
|
||||||
GetPod(id string) (api.Pod, error)
|
GetPod(id string) (*api.Pod, error)
|
||||||
DeletePod(id string) error
|
DeletePod(id string) error
|
||||||
CreatePod(api.Pod) (api.Pod, error)
|
CreatePod(*api.Pod) (*api.Pod, error)
|
||||||
UpdatePod(api.Pod) (api.Pod, error)
|
UpdatePod(*api.Pod) (*api.Pod, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplicationControllerInterface has methods to work with ReplicationController resources.
|
// ReplicationControllerInterface has methods to work with ReplicationController resources.
|
||||||
type ReplicationControllerInterface interface {
|
type ReplicationControllerInterface interface {
|
||||||
ListReplicationControllers(selector labels.Selector) (api.ReplicationControllerList, error)
|
ListReplicationControllers(selector labels.Selector) (*api.ReplicationControllerList, error)
|
||||||
GetReplicationController(id string) (api.ReplicationController, error)
|
GetReplicationController(id string) (*api.ReplicationController, error)
|
||||||
CreateReplicationController(api.ReplicationController) (api.ReplicationController, error)
|
CreateReplicationController(*api.ReplicationController) (*api.ReplicationController, error)
|
||||||
UpdateReplicationController(api.ReplicationController) (api.ReplicationController, error)
|
UpdateReplicationController(*api.ReplicationController) (*api.ReplicationController, error)
|
||||||
DeleteReplicationController(string) error
|
DeleteReplicationController(string) error
|
||||||
WatchReplicationControllers(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchReplicationControllers(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceInterface has methods to work with Service resources.
|
// ServiceInterface has methods to work with Service resources.
|
||||||
type ServiceInterface interface {
|
type ServiceInterface interface {
|
||||||
ListServices(selector labels.Selector) (api.ServiceList, error)
|
ListServices(selector labels.Selector) (*api.ServiceList, error)
|
||||||
GetService(id string) (api.Service, error)
|
GetService(id string) (*api.Service, error)
|
||||||
CreateService(api.Service) (api.Service, error)
|
CreateService(*api.Service) (*api.Service, error)
|
||||||
UpdateService(api.Service) (api.Service, error)
|
UpdateService(*api.Service) (*api.Service, error)
|
||||||
DeleteService(string) error
|
DeleteService(string) error
|
||||||
WatchServices(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchServices(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndpointsInterface has methods to work with Endpoints resources
|
// EndpointsInterface has methods to work with Endpoints resources
|
||||||
type EndpointsInterface interface {
|
type EndpointsInterface interface {
|
||||||
ListEndpoints(selector labels.Selector) (api.EndpointsList, error)
|
ListEndpoints(selector labels.Selector) (*api.EndpointsList, error)
|
||||||
WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ type VersionInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MinionInterface interface {
|
type MinionInterface interface {
|
||||||
ListMinions() (api.MinionList, error)
|
ListMinions() (*api.MinionList, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client is the actual implementation of a Kubernetes client.
|
// Client is the actual implementation of a Kubernetes client.
|
||||||
@@ -222,7 +222,7 @@ func (c *RESTClient) doRequest(request *http.Request) ([]byte, error) {
|
|||||||
// Did the server give us a status response?
|
// Did the server give us a status response?
|
||||||
isStatusResponse := false
|
isStatusResponse := false
|
||||||
var status api.Status
|
var status api.Status
|
||||||
if err := runtime.DecodeInto(body, &status); err == nil && status.Status != "" {
|
if err := runtime.DefaultCodec.DecodeInto(body, &status); err == nil && status.Status != "" {
|
||||||
isStatusResponse = true
|
isStatusResponse = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,14 +247,16 @@ func (c *RESTClient) doRequest(request *http.Request) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListPods takes a selector, and returns the list of pods that match that selector.
|
// ListPods takes a selector, and returns the list of pods that match that selector.
|
||||||
func (c *Client) ListPods(selector labels.Selector) (result api.PodList, err error) {
|
func (c *Client) ListPods(selector labels.Selector) (result *api.PodList, err error) {
|
||||||
err = c.Get().Path("pods").SelectorParam("labels", selector).Do().Into(&result)
|
result = &api.PodList{}
|
||||||
|
err = c.Get().Path("pods").SelectorParam("labels", selector).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPod takes the id of the pod, and returns the corresponding Pod object, and an error if it occurs
|
// GetPod takes the id of the pod, and returns the corresponding Pod object, and an error if it occurs
|
||||||
func (c *Client) GetPod(id string) (result api.Pod, err error) {
|
func (c *Client) GetPod(id string) (result *api.Pod, err error) {
|
||||||
err = c.Get().Path("pods").Path(id).Do().Into(&result)
|
result = &api.Pod{}
|
||||||
|
err = c.Get().Path("pods").Path(id).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,46 +266,52 @@ func (c *Client) DeletePod(id string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreatePod takes the representation of a pod. Returns the server's representation of the pod, and an error, if it occurs.
|
// CreatePod takes the representation of a pod. Returns the server's representation of the pod, and an error, if it occurs.
|
||||||
func (c *Client) CreatePod(pod api.Pod) (result api.Pod, err error) {
|
func (c *Client) CreatePod(pod *api.Pod) (result *api.Pod, err error) {
|
||||||
err = c.Post().Path("pods").Body(pod).Do().Into(&result)
|
result = &api.Pod{}
|
||||||
|
err = c.Post().Path("pods").Body(pod).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePod takes the representation of a pod to update. Returns the server's representation of the pod, and an error, if it occurs.
|
// UpdatePod takes the representation of a pod to update. Returns the server's representation of the pod, and an error, if it occurs.
|
||||||
func (c *Client) UpdatePod(pod api.Pod) (result api.Pod, err error) {
|
func (c *Client) UpdatePod(pod *api.Pod) (result *api.Pod, err error) {
|
||||||
|
result = &api.Pod{}
|
||||||
if pod.ResourceVersion == 0 {
|
if pod.ResourceVersion == 0 {
|
||||||
err = fmt.Errorf("invalid update object, missing resource version: %v", pod)
|
err = fmt.Errorf("invalid update object, missing resource version: %v", pod)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.Put().Path("pods").Path(pod.ID).Body(pod).Do().Into(&result)
|
err = c.Put().Path("pods").Path(pod.ID).Body(pod).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListReplicationControllers takes a selector, and returns the list of replication controllers that match that selector.
|
// ListReplicationControllers takes a selector, and returns the list of replication controllers that match that selector.
|
||||||
func (c *Client) ListReplicationControllers(selector labels.Selector) (result api.ReplicationControllerList, err error) {
|
func (c *Client) ListReplicationControllers(selector labels.Selector) (result *api.ReplicationControllerList, err error) {
|
||||||
err = c.Get().Path("replicationControllers").SelectorParam("labels", selector).Do().Into(&result)
|
result = &api.ReplicationControllerList{}
|
||||||
|
err = c.Get().Path("replicationControllers").SelectorParam("labels", selector).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReplicationController returns information about a particular replication controller.
|
// GetReplicationController returns information about a particular replication controller.
|
||||||
func (c *Client) GetReplicationController(id string) (result api.ReplicationController, err error) {
|
func (c *Client) GetReplicationController(id string) (result *api.ReplicationController, err error) {
|
||||||
err = c.Get().Path("replicationControllers").Path(id).Do().Into(&result)
|
result = &api.ReplicationController{}
|
||||||
|
err = c.Get().Path("replicationControllers").Path(id).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateReplicationController creates a new replication controller.
|
// CreateReplicationController creates a new replication controller.
|
||||||
func (c *Client) CreateReplicationController(controller api.ReplicationController) (result api.ReplicationController, err error) {
|
func (c *Client) CreateReplicationController(controller *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||||
err = c.Post().Path("replicationControllers").Body(controller).Do().Into(&result)
|
result = &api.ReplicationController{}
|
||||||
|
err = c.Post().Path("replicationControllers").Body(controller).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateReplicationController updates an existing replication controller.
|
// UpdateReplicationController updates an existing replication controller.
|
||||||
func (c *Client) UpdateReplicationController(controller api.ReplicationController) (result api.ReplicationController, err error) {
|
func (c *Client) UpdateReplicationController(controller *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||||
|
result = &api.ReplicationController{}
|
||||||
if controller.ResourceVersion == 0 {
|
if controller.ResourceVersion == 0 {
|
||||||
err = fmt.Errorf("invalid update object, missing resource version: %v", controller)
|
err = fmt.Errorf("invalid update object, missing resource version: %v", controller)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.Put().Path("replicationControllers").Path(controller.ID).Body(controller).Do().Into(&result)
|
err = c.Put().Path("replicationControllers").Path(controller.ID).Body(controller).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,30 +332,34 @@ func (c *Client) WatchReplicationControllers(label, field labels.Selector, resou
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListServices takes a selector, and returns the list of services that match that selector
|
// ListServices takes a selector, and returns the list of services that match that selector
|
||||||
func (c *Client) ListServices(selector labels.Selector) (result api.ServiceList, err error) {
|
func (c *Client) ListServices(selector labels.Selector) (result *api.ServiceList, err error) {
|
||||||
err = c.Get().Path("services").SelectorParam("labels", selector).Do().Into(&result)
|
result = &api.ServiceList{}
|
||||||
|
err = c.Get().Path("services").SelectorParam("labels", selector).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetService returns information about a particular service.
|
// GetService returns information about a particular service.
|
||||||
func (c *Client) GetService(id string) (result api.Service, err error) {
|
func (c *Client) GetService(id string) (result *api.Service, err error) {
|
||||||
err = c.Get().Path("services").Path(id).Do().Into(&result)
|
result = &api.Service{}
|
||||||
|
err = c.Get().Path("services").Path(id).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateService creates a new service.
|
// CreateService creates a new service.
|
||||||
func (c *Client) CreateService(svc api.Service) (result api.Service, err error) {
|
func (c *Client) CreateService(svc *api.Service) (result *api.Service, err error) {
|
||||||
err = c.Post().Path("services").Body(svc).Do().Into(&result)
|
result = &api.Service{}
|
||||||
|
err = c.Post().Path("services").Body(svc).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateService updates an existing service.
|
// UpdateService updates an existing service.
|
||||||
func (c *Client) UpdateService(svc api.Service) (result api.Service, err error) {
|
func (c *Client) UpdateService(svc *api.Service) (result *api.Service, err error) {
|
||||||
|
result = &api.Service{}
|
||||||
if svc.ResourceVersion == 0 {
|
if svc.ResourceVersion == 0 {
|
||||||
err = fmt.Errorf("invalid update object, missing resource version: %v", svc)
|
err = fmt.Errorf("invalid update object, missing resource version: %v", svc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.Put().Path("services").Path(svc.ID).Body(svc).Do().Into(&result)
|
err = c.Put().Path("services").Path(svc.ID).Body(svc).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,8 +380,9 @@ func (c *Client) WatchServices(label, field labels.Selector, resourceVersion uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListEndpoints takes a selector, and returns the list of endpoints that match that selector
|
// ListEndpoints takes a selector, and returns the list of endpoints that match that selector
|
||||||
func (c *Client) ListEndpoints(selector labels.Selector) (result api.EndpointsList, err error) {
|
func (c *Client) ListEndpoints(selector labels.Selector) (result *api.EndpointsList, err error) {
|
||||||
err = c.Get().Path("endpoints").SelectorParam("labels", selector).Do().Into(&result)
|
result = &api.EndpointsList{}
|
||||||
|
err = c.Get().Path("endpoints").SelectorParam("labels", selector).Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +412,8 @@ func (c *Client) ServerVersion() (*version.Info, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListMinions lists all the minions in the cluster.
|
// ListMinions lists all the minions in the cluster.
|
||||||
func (c *Client) ListMinions() (minionList api.MinionList, err error) {
|
func (c *Client) ListMinions() (result *api.MinionList, err error) {
|
||||||
err = c.Get().Path("minions").Do().Into(&minionList)
|
result = &api.MinionList{}
|
||||||
|
err = c.Get().Path("minions").Do().Into(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func TestValidatesHostParameter(t *testing.T) {
|
|||||||
func TestListEmptyPods(t *testing.T) {
|
func TestListEmptyPods(t *testing.T) {
|
||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "GET", Path: "/pods"},
|
Request: testRequest{Method: "GET", Path: "/pods"},
|
||||||
Response: Response{StatusCode: 200, Body: api.PodList{}},
|
Response: Response{StatusCode: 200, Body: &api.PodList{}},
|
||||||
}
|
}
|
||||||
podList, err := c.Setup().ListPods(labels.Everything())
|
podList, err := c.Setup().ListPods(labels.Everything())
|
||||||
c.Validate(t, podList, err)
|
c.Validate(t, podList, err)
|
||||||
@@ -83,7 +83,7 @@ func TestListPods(t *testing.T) {
|
|||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "GET", Path: "/pods"},
|
Request: testRequest{Method: "GET", Path: "/pods"},
|
||||||
Response: Response{StatusCode: 200,
|
Response: Response{StatusCode: 200,
|
||||||
Body: api.PodList{
|
Body: &api.PodList{
|
||||||
Items: []api.Pod{
|
Items: []api.Pod{
|
||||||
{
|
{
|
||||||
CurrentState: api.PodState{
|
CurrentState: api.PodState{
|
||||||
@@ -113,7 +113,7 @@ func TestListPodsLabels(t *testing.T) {
|
|||||||
Request: testRequest{Method: "GET", Path: "/pods", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}},
|
Request: testRequest{Method: "GET", Path: "/pods", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}},
|
||||||
Response: Response{
|
Response: Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: api.PodList{
|
Body: &api.PodList{
|
||||||
Items: []api.Pod{
|
Items: []api.Pod{
|
||||||
{
|
{
|
||||||
CurrentState: api.PodState{
|
CurrentState: api.PodState{
|
||||||
@@ -140,7 +140,7 @@ func TestGetPod(t *testing.T) {
|
|||||||
Request: testRequest{Method: "GET", Path: "/pods/foo"},
|
Request: testRequest{Method: "GET", Path: "/pods/foo"},
|
||||||
Response: Response{
|
Response: Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: api.Pod{
|
Body: &api.Pod{
|
||||||
CurrentState: api.PodState{
|
CurrentState: api.PodState{
|
||||||
Status: "Foobar",
|
Status: "Foobar",
|
||||||
},
|
},
|
||||||
@@ -165,7 +165,7 @@ func TestDeletePod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCreatePod(t *testing.T) {
|
func TestCreatePod(t *testing.T) {
|
||||||
requestPod := api.Pod{
|
requestPod := &api.Pod{
|
||||||
CurrentState: api.PodState{
|
CurrentState: api.PodState{
|
||||||
Status: "Foobar",
|
Status: "Foobar",
|
||||||
},
|
},
|
||||||
@@ -186,7 +186,7 @@ func TestCreatePod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdatePod(t *testing.T) {
|
func TestUpdatePod(t *testing.T) {
|
||||||
requestPod := api.Pod{
|
requestPod := &api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: 1},
|
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: 1},
|
||||||
CurrentState: api.PodState{
|
CurrentState: api.PodState{
|
||||||
Status: "Foobar",
|
Status: "Foobar",
|
||||||
@@ -208,7 +208,7 @@ func TestListControllers(t *testing.T) {
|
|||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "GET", Path: "/replicationControllers"},
|
Request: testRequest{Method: "GET", Path: "/replicationControllers"},
|
||||||
Response: Response{StatusCode: 200,
|
Response: Response{StatusCode: 200,
|
||||||
Body: api.ReplicationControllerList{
|
Body: &api.ReplicationControllerList{
|
||||||
Items: []api.ReplicationController{
|
Items: []api.ReplicationController{
|
||||||
{
|
{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
@@ -234,7 +234,7 @@ func TestGetController(t *testing.T) {
|
|||||||
Request: testRequest{Method: "GET", Path: "/replicationControllers/foo"},
|
Request: testRequest{Method: "GET", Path: "/replicationControllers/foo"},
|
||||||
Response: Response{
|
Response: Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: api.ReplicationController{
|
Body: &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
DesiredState: api.ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
Replicas: 2,
|
Replicas: 2,
|
||||||
@@ -251,14 +251,14 @@ func TestGetController(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateController(t *testing.T) {
|
func TestUpdateController(t *testing.T) {
|
||||||
requestController := api.ReplicationController{
|
requestController := &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: 1},
|
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: 1},
|
||||||
}
|
}
|
||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "PUT", Path: "/replicationControllers/foo"},
|
Request: testRequest{Method: "PUT", Path: "/replicationControllers/foo"},
|
||||||
Response: Response{
|
Response: Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: api.ReplicationController{
|
Body: &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
DesiredState: api.ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
Replicas: 2,
|
Replicas: 2,
|
||||||
@@ -284,14 +284,14 @@ func TestDeleteController(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateController(t *testing.T) {
|
func TestCreateController(t *testing.T) {
|
||||||
requestController := api.ReplicationController{
|
requestController := &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
}
|
}
|
||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "POST", Path: "/replicationControllers", Body: requestController},
|
Request: testRequest{Method: "POST", Path: "/replicationControllers", Body: requestController},
|
||||||
Response: Response{
|
Response: Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: api.ReplicationController{
|
Body: &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
DesiredState: api.ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
Replicas: 2,
|
Replicas: 2,
|
||||||
@@ -307,9 +307,9 @@ func TestCreateController(t *testing.T) {
|
|||||||
c.Validate(t, receivedController, err)
|
c.Validate(t, receivedController, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func body(obj interface{}, raw *string) *string {
|
func body(obj runtime.Object, raw *string) *string {
|
||||||
if obj != nil {
|
if obj != nil {
|
||||||
bs, _ := runtime.Encode(obj)
|
bs, _ := runtime.DefaultCodec.Encode(obj)
|
||||||
body := string(bs)
|
body := string(bs)
|
||||||
return &body
|
return &body
|
||||||
}
|
}
|
||||||
@@ -321,13 +321,13 @@ type testRequest struct {
|
|||||||
Path string
|
Path string
|
||||||
Header string
|
Header string
|
||||||
Query url.Values
|
Query url.Values
|
||||||
Body interface{}
|
Body runtime.Object
|
||||||
RawBody *string
|
RawBody *string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
StatusCode int
|
StatusCode int
|
||||||
Body interface{}
|
Body runtime.Object
|
||||||
RawBody *string
|
RawBody *string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +338,6 @@ type testClient struct {
|
|||||||
Error bool
|
Error bool
|
||||||
server *httptest.Server
|
server *httptest.Server
|
||||||
handler *util.FakeHandler
|
handler *util.FakeHandler
|
||||||
Target interface{}
|
|
||||||
// For query args, an optional function to validate the contents
|
// For query args, an optional function to validate the contents
|
||||||
// useful when the contents can change but still be correct.
|
// useful when the contents can change but still be correct.
|
||||||
// Maps from query arg key to validator.
|
// Maps from query arg key to validator.
|
||||||
@@ -363,7 +362,23 @@ func (c *testClient) Setup() *testClient {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testClient) Validate(t *testing.T, received interface{}, err error) {
|
func (c *testClient) Validate(t *testing.T, received runtime.Object, err error) {
|
||||||
|
c.ValidateCommon(t, err)
|
||||||
|
|
||||||
|
if c.Response.Body != nil && !reflect.DeepEqual(c.Response.Body, received) {
|
||||||
|
t.Errorf("bad response for request %#v: expected %s, got %s", c.Request, c.Response.Body, received)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testClient) ValidateRaw(t *testing.T, received []byte, err error) {
|
||||||
|
c.ValidateCommon(t, err)
|
||||||
|
|
||||||
|
if c.Response.Body != nil && !reflect.DeepEqual(c.Response.Body, received) {
|
||||||
|
t.Errorf("bad response for request %#v: expected %s, got %s", c.Request, c.Response.Body, received)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testClient) ValidateCommon(t *testing.T, err error) {
|
||||||
defer c.server.Close()
|
defer c.server.Close()
|
||||||
|
|
||||||
if c.Error {
|
if c.Error {
|
||||||
@@ -401,17 +416,13 @@ func (c *testClient) Validate(t *testing.T, received interface{}, err error) {
|
|||||||
if expected, received := requestBody, c.handler.RequestBody; expected != nil && *expected != received {
|
if expected, received := requestBody, c.handler.RequestBody; expected != nil && *expected != received {
|
||||||
t.Errorf("bad body for request %#v: expected %s, got %s", c.Request, *expected, received)
|
t.Errorf("bad body for request %#v: expected %s, got %s", c.Request, *expected, received)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Response.Body != nil && !reflect.DeepEqual(c.Response.Body, received) {
|
|
||||||
t.Errorf("bad response for request %#v: expected %s, got %s", c.Request, c.Response.Body, received)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListServices(t *testing.T) {
|
func TestListServices(t *testing.T) {
|
||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "GET", Path: "/services"},
|
Request: testRequest{Method: "GET", Path: "/services"},
|
||||||
Response: Response{StatusCode: 200,
|
Response: Response{StatusCode: 200,
|
||||||
Body: api.ServiceList{
|
Body: &api.ServiceList{
|
||||||
Items: []api.Service{
|
Items: []api.Service{
|
||||||
{
|
{
|
||||||
JSONBase: api.JSONBase{ID: "name"},
|
JSONBase: api.JSONBase{ID: "name"},
|
||||||
@@ -435,7 +446,7 @@ func TestListServicesLabels(t *testing.T) {
|
|||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "GET", Path: "/services", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}},
|
Request: testRequest{Method: "GET", Path: "/services", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}},
|
||||||
Response: Response{StatusCode: 200,
|
Response: Response{StatusCode: 200,
|
||||||
Body: api.ServiceList{
|
Body: &api.ServiceList{
|
||||||
Items: []api.Service{
|
Items: []api.Service{
|
||||||
{
|
{
|
||||||
JSONBase: api.JSONBase{ID: "name"},
|
JSONBase: api.JSONBase{ID: "name"},
|
||||||
@@ -464,7 +475,7 @@ func TestGetService(t *testing.T) {
|
|||||||
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
|
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
|
||||||
}
|
}
|
||||||
response, err := c.Setup().GetService("1")
|
response, err := c.Setup().GetService("1")
|
||||||
c.Validate(t, &response, err)
|
c.Validate(t, response, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateService(t *testing.T) {
|
func TestCreateService(t *testing.T) {
|
||||||
@@ -472,18 +483,18 @@ func TestCreateService(t *testing.T) {
|
|||||||
Request: testRequest{Method: "POST", Path: "/services", Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
|
Request: testRequest{Method: "POST", Path: "/services", Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
|
||||||
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
|
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
|
||||||
}).Setup()
|
}).Setup()
|
||||||
response, err := c.Setup().CreateService(api.Service{JSONBase: api.JSONBase{ID: "service-1"}})
|
response, err := c.Setup().CreateService(&api.Service{JSONBase: api.JSONBase{ID: "service-1"}})
|
||||||
c.Validate(t, &response, err)
|
c.Validate(t, response, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateService(t *testing.T) {
|
func TestUpdateService(t *testing.T) {
|
||||||
svc := api.Service{JSONBase: api.JSONBase{ID: "service-1", ResourceVersion: 1}}
|
svc := &api.Service{JSONBase: api.JSONBase{ID: "service-1", ResourceVersion: 1}}
|
||||||
c := &testClient{
|
c := &testClient{
|
||||||
Request: testRequest{Method: "PUT", Path: "/services/service-1", Body: &svc},
|
Request: testRequest{Method: "PUT", Path: "/services/service-1", Body: svc},
|
||||||
Response: Response{StatusCode: 200, Body: &svc},
|
Response: Response{StatusCode: 200, Body: svc},
|
||||||
}
|
}
|
||||||
response, err := c.Setup().UpdateService(svc)
|
response, err := c.Setup().UpdateService(svc)
|
||||||
c.Validate(t, &response, err)
|
c.Validate(t, response, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteService(t *testing.T) {
|
func TestDeleteService(t *testing.T) {
|
||||||
@@ -503,8 +514,8 @@ func TestDoRequest(t *testing.T) {
|
|||||||
{Client: NewOrDie("localhost", &AuthInfo{"foo", "bar"}), Request: testRequest{Method: "GET", Path: "auth", Header: "Authorization"}, Response: Response{StatusCode: 200}},
|
{Client: NewOrDie("localhost", &AuthInfo{"foo", "bar"}), Request: testRequest{Method: "GET", Path: "auth", Header: "Authorization"}, Response: Response{StatusCode: 200}},
|
||||||
{Client: &Client{&RESTClient{httpClient: http.DefaultClient}}, Request: testRequest{Method: "GET", Path: "nocertificate"}, Error: true},
|
{Client: &Client{&RESTClient{httpClient: http.DefaultClient}}, Request: testRequest{Method: "GET", Path: "nocertificate"}, Error: true},
|
||||||
{Request: testRequest{Method: "GET", Path: "error"}, Response: Response{StatusCode: 500}, Error: true},
|
{Request: testRequest{Method: "GET", Path: "error"}, Response: Response{StatusCode: 500}, Error: true},
|
||||||
{Request: testRequest{Method: "POST", Path: "faildecode"}, Response: Response{StatusCode: 200, RawBody: &invalid}, Target: &struct{}{}},
|
{Request: testRequest{Method: "POST", Path: "faildecode"}, Response: Response{StatusCode: 200, RawBody: &invalid}},
|
||||||
{Request: testRequest{Method: "GET", Path: "failread"}, Response: Response{StatusCode: 200, RawBody: &invalid}, Target: &struct{}{}},
|
{Request: testRequest{Method: "GET", Path: "failread"}, Response: Response{StatusCode: 200, RawBody: &invalid}},
|
||||||
}
|
}
|
||||||
for _, c := range testClients {
|
for _, c := range testClients {
|
||||||
client := c.Setup()
|
client := c.Setup()
|
||||||
@@ -516,13 +527,13 @@ func TestDoRequest(t *testing.T) {
|
|||||||
URL: prefix,
|
URL: prefix,
|
||||||
}
|
}
|
||||||
response, err := client.doRequest(request)
|
response, err := client.doRequest(request)
|
||||||
c.Validate(t, response, err)
|
c.ValidateRaw(t, response, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDoRequestAccepted(t *testing.T) {
|
func TestDoRequestAccepted(t *testing.T) {
|
||||||
status := api.Status{Status: api.StatusWorking}
|
status := &api.Status{Status: api.StatusWorking}
|
||||||
expectedBody, _ := runtime.Encode(status)
|
expectedBody, _ := runtime.DefaultCodec.Encode(status)
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 202,
|
StatusCode: 202,
|
||||||
ResponseBody: string(expectedBody),
|
ResponseBody: string(expectedBody),
|
||||||
@@ -548,7 +559,7 @@ func TestDoRequestAccepted(t *testing.T) {
|
|||||||
t.Errorf("Unexpected kind of error: %#v", err)
|
t.Errorf("Unexpected kind of error: %#v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(se.Status, status) {
|
if !reflect.DeepEqual(&se.Status, status) {
|
||||||
t.Errorf("Unexpected status: %#v", se.Status)
|
t.Errorf("Unexpected status: %#v", se.Status)
|
||||||
}
|
}
|
||||||
if body != nil {
|
if body != nil {
|
||||||
@@ -558,8 +569,8 @@ func TestDoRequestAccepted(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDoRequestAcceptedSuccess(t *testing.T) {
|
func TestDoRequestAcceptedSuccess(t *testing.T) {
|
||||||
status := api.Status{Status: api.StatusSuccess}
|
status := &api.Status{Status: api.StatusSuccess}
|
||||||
expectedBody, _ := runtime.Encode(status)
|
expectedBody, _ := runtime.DefaultCodec.Encode(status)
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 202,
|
StatusCode: 202,
|
||||||
ResponseBody: string(expectedBody),
|
ResponseBody: string(expectedBody),
|
||||||
@@ -579,11 +590,11 @@ func TestDoRequestAcceptedSuccess(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error %#v", err)
|
t.Errorf("Unexpected error %#v", err)
|
||||||
}
|
}
|
||||||
statusOut, err := runtime.Decode(body)
|
statusOut, err := runtime.DefaultCodec.Decode(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error %#v", err)
|
t.Errorf("Unexpected error %#v", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(&status, statusOut) {
|
if !reflect.DeepEqual(status, statusOut) {
|
||||||
t.Errorf("Unexpected mis-match. Expected %#v. Saw %#v", status, statusOut)
|
t.Errorf("Unexpected mis-match. Expected %#v. Saw %#v", status, statusOut)
|
||||||
}
|
}
|
||||||
fakeHandler.ValidateRequest(t, "/foo/bar", "GET", nil)
|
fakeHandler.ValidateRequest(t, "/foo/bar", "GET", nil)
|
||||||
@@ -622,5 +633,5 @@ func TestListMinions(t *testing.T) {
|
|||||||
Response: Response{StatusCode: 200, Body: &api.MinionList{JSONBase: api.JSONBase{ID: "minion-1"}}},
|
Response: Response{StatusCode: 200, Body: &api.MinionList{JSONBase: api.JSONBase{ID: "minion-1"}}},
|
||||||
}
|
}
|
||||||
response, err := c.Setup().ListMinions()
|
response, err := c.Setup().ListMinions()
|
||||||
c.Validate(t, &response, err)
|
c.Validate(t, response, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ type Fake struct {
|
|||||||
Watch watch.Interface
|
Watch watch.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) ListPods(selector labels.Selector) (api.PodList, error) {
|
func (c *Fake) ListPods(selector labels.Selector) (*api.PodList, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "list-pods"})
|
c.Actions = append(c.Actions, FakeAction{Action: "list-pods"})
|
||||||
return *runtime.CopyOrDie(c.Pods).(*api.PodList), nil
|
return runtime.DefaultScheme.CopyOrDie(&c.Pods).(*api.PodList), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) GetPod(name string) (api.Pod, error) {
|
func (c *Fake) GetPod(name string) (*api.Pod, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "get-pod", Value: name})
|
c.Actions = append(c.Actions, FakeAction{Action: "get-pod", Value: name})
|
||||||
return api.Pod{}, nil
|
return &api.Pod{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) DeletePod(name string) error {
|
func (c *Fake) DeletePod(name string) error {
|
||||||
@@ -57,34 +57,34 @@ func (c *Fake) DeletePod(name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) CreatePod(pod api.Pod) (api.Pod, error) {
|
func (c *Fake) CreatePod(pod *api.Pod) (*api.Pod, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "create-pod"})
|
c.Actions = append(c.Actions, FakeAction{Action: "create-pod"})
|
||||||
return api.Pod{}, nil
|
return &api.Pod{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) UpdatePod(pod api.Pod) (api.Pod, error) {
|
func (c *Fake) UpdatePod(pod *api.Pod) (*api.Pod, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "update-pod", Value: pod.ID})
|
c.Actions = append(c.Actions, FakeAction{Action: "update-pod", Value: pod.ID})
|
||||||
return api.Pod{}, nil
|
return &api.Pod{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) ListReplicationControllers(selector labels.Selector) (api.ReplicationControllerList, error) {
|
func (c *Fake) ListReplicationControllers(selector labels.Selector) (*api.ReplicationControllerList, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "list-controllers"})
|
c.Actions = append(c.Actions, FakeAction{Action: "list-controllers"})
|
||||||
return api.ReplicationControllerList{}, nil
|
return &api.ReplicationControllerList{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) GetReplicationController(name string) (api.ReplicationController, error) {
|
func (c *Fake) GetReplicationController(name string) (*api.ReplicationController, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "get-controller", Value: name})
|
c.Actions = append(c.Actions, FakeAction{Action: "get-controller", Value: name})
|
||||||
return *runtime.CopyOrDie(c.Ctrl).(*api.ReplicationController), nil
|
return runtime.DefaultScheme.CopyOrDie(&c.Ctrl).(*api.ReplicationController), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) CreateReplicationController(controller api.ReplicationController) (api.ReplicationController, error) {
|
func (c *Fake) CreateReplicationController(controller *api.ReplicationController) (*api.ReplicationController, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "create-controller", Value: controller})
|
c.Actions = append(c.Actions, FakeAction{Action: "create-controller", Value: controller})
|
||||||
return api.ReplicationController{}, nil
|
return &api.ReplicationController{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) UpdateReplicationController(controller api.ReplicationController) (api.ReplicationController, error) {
|
func (c *Fake) UpdateReplicationController(controller *api.ReplicationController) (*api.ReplicationController, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "update-controller", Value: controller})
|
c.Actions = append(c.Actions, FakeAction{Action: "update-controller", Value: controller})
|
||||||
return api.ReplicationController{}, nil
|
return &api.ReplicationController{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) DeleteReplicationController(controller string) error {
|
func (c *Fake) DeleteReplicationController(controller string) error {
|
||||||
@@ -97,24 +97,24 @@ func (c *Fake) WatchReplicationControllers(label, field labels.Selector, resourc
|
|||||||
return c.Watch, nil
|
return c.Watch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) ListServices(selector labels.Selector) (api.ServiceList, error) {
|
func (c *Fake) ListServices(selector labels.Selector) (*api.ServiceList, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "list-services"})
|
c.Actions = append(c.Actions, FakeAction{Action: "list-services"})
|
||||||
return c.ServiceList, c.Err
|
return &c.ServiceList, c.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) GetService(name string) (api.Service, error) {
|
func (c *Fake) GetService(name string) (*api.Service, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "get-service", Value: name})
|
c.Actions = append(c.Actions, FakeAction{Action: "get-service", Value: name})
|
||||||
return api.Service{}, nil
|
return &api.Service{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) CreateService(service api.Service) (api.Service, error) {
|
func (c *Fake) CreateService(service *api.Service) (*api.Service, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "create-service", Value: service})
|
c.Actions = append(c.Actions, FakeAction{Action: "create-service", Value: service})
|
||||||
return api.Service{}, nil
|
return &api.Service{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) UpdateService(service api.Service) (api.Service, error) {
|
func (c *Fake) UpdateService(service *api.Service) (*api.Service, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "update-service", Value: service})
|
c.Actions = append(c.Actions, FakeAction{Action: "update-service", Value: service})
|
||||||
return api.Service{}, nil
|
return &api.Service{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) DeleteService(service string) error {
|
func (c *Fake) DeleteService(service string) error {
|
||||||
@@ -127,9 +127,9 @@ func (c *Fake) WatchServices(label, field labels.Selector, resourceVersion uint6
|
|||||||
return c.Watch, c.Err
|
return c.Watch, c.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) ListEndpoints(selector labels.Selector) (api.EndpointsList, error) {
|
func (c *Fake) ListEndpoints(selector labels.Selector) (*api.EndpointsList, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "list-endpoints"})
|
c.Actions = append(c.Actions, FakeAction{Action: "list-endpoints"})
|
||||||
return c.EndpointsList, c.Err
|
return runtime.DefaultScheme.CopyOrDie(&c.EndpointsList).(*api.EndpointsList), c.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
|
func (c *Fake) WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
|
||||||
@@ -143,7 +143,7 @@ func (c *Fake) ServerVersion() (*version.Info, error) {
|
|||||||
return &versionInfo, nil
|
return &versionInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Fake) ListMinions() (api.MinionList, error) {
|
func (c *Fake) ListMinions() (*api.MinionList, error) {
|
||||||
c.Actions = append(c.Actions, FakeAction{Action: "list-minions", Value: nil})
|
c.Actions = append(c.Actions, FakeAction{Action: "list-minions", Value: nil})
|
||||||
return api.MinionList{}, nil
|
return &api.MinionList{}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,8 @@ func (r *Request) Timeout(d time.Duration) *Request {
|
|||||||
// If obj is a string, try to read a file of that name.
|
// If obj is a string, try to read a file of that name.
|
||||||
// If obj is a []byte, send it directly.
|
// If obj is a []byte, send it directly.
|
||||||
// If obj is an io.Reader, use it directly.
|
// If obj is an io.Reader, use it directly.
|
||||||
// Otherwise, assume obj is an api type and marshall it correctly.
|
// If obj is a runtime.Object, marshal it correctly.
|
||||||
|
// Otherwise, set an error.
|
||||||
func (r *Request) Body(obj interface{}) *Request {
|
func (r *Request) Body(obj interface{}) *Request {
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return r
|
return r
|
||||||
@@ -204,13 +205,15 @@ func (r *Request) Body(obj interface{}) *Request {
|
|||||||
r.body = bytes.NewBuffer(t)
|
r.body = bytes.NewBuffer(t)
|
||||||
case io.Reader:
|
case io.Reader:
|
||||||
r.body = t
|
r.body = t
|
||||||
default:
|
case runtime.Object:
|
||||||
data, err := runtime.Encode(obj)
|
data, err := runtime.DefaultCodec.Encode(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.err = err
|
r.err = err
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
r.body = bytes.NewBuffer(data)
|
r.body = bytes.NewBuffer(data)
|
||||||
|
default:
|
||||||
|
r.err = fmt.Errorf("Unknown type used for body: %#v", obj)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -314,19 +317,19 @@ func (r Result) Raw() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the result as an object.
|
// Get returns the result as an object.
|
||||||
func (r Result) Get() (interface{}, error) {
|
func (r Result) Get() (runtime.Object, error) {
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return nil, r.err
|
return nil, r.err
|
||||||
}
|
}
|
||||||
return runtime.Decode(r.body)
|
return runtime.DefaultCodec.Decode(r.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Into stores the result into obj, if possible.
|
// Into stores the result into obj, if possible.
|
||||||
func (r Result) Into(obj interface{}) error {
|
func (r Result) Into(obj runtime.Object) error {
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return r.err
|
return r.err
|
||||||
}
|
}
|
||||||
return runtime.DecodeInto(r.body, obj)
|
return runtime.DefaultCodec.DecodeInto(r.body, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error returns the error executing the request, nil if no error occurred.
|
// Error returns the error executing the request, nil if no error occurred.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import (
|
|||||||
func TestDoRequestNewWay(t *testing.T) {
|
func TestDoRequestNewWay(t *testing.T) {
|
||||||
reqBody := "request body"
|
reqBody := "request body"
|
||||||
expectedObj := &api.Service{Port: 12345}
|
expectedObj := &api.Service{Port: 12345}
|
||||||
expectedBody, _ := runtime.Encode(expectedObj)
|
expectedBody, _ := runtime.DefaultCodec.Encode(expectedObj)
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(expectedBody),
|
ResponseBody: string(expectedBody),
|
||||||
@@ -71,9 +71,9 @@ func TestDoRequestNewWay(t *testing.T) {
|
|||||||
|
|
||||||
func TestDoRequestNewWayReader(t *testing.T) {
|
func TestDoRequestNewWayReader(t *testing.T) {
|
||||||
reqObj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
reqObj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
reqBodyExpected, _ := runtime.Encode(reqObj)
|
reqBodyExpected, _ := runtime.DefaultCodec.Encode(reqObj)
|
||||||
expectedObj := &api.Service{Port: 12345}
|
expectedObj := &api.Service{Port: 12345}
|
||||||
expectedBody, _ := runtime.Encode(expectedObj)
|
expectedBody, _ := runtime.DefaultCodec.Encode(expectedObj)
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(expectedBody),
|
ResponseBody: string(expectedBody),
|
||||||
@@ -108,9 +108,9 @@ func TestDoRequestNewWayReader(t *testing.T) {
|
|||||||
|
|
||||||
func TestDoRequestNewWayObj(t *testing.T) {
|
func TestDoRequestNewWayObj(t *testing.T) {
|
||||||
reqObj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
reqObj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
reqBodyExpected, _ := runtime.Encode(reqObj)
|
reqBodyExpected, _ := runtime.DefaultCodec.Encode(reqObj)
|
||||||
expectedObj := &api.Service{Port: 12345}
|
expectedObj := &api.Service{Port: 12345}
|
||||||
expectedBody, _ := runtime.Encode(expectedObj)
|
expectedBody, _ := runtime.DefaultCodec.Encode(expectedObj)
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(expectedBody),
|
ResponseBody: string(expectedBody),
|
||||||
@@ -144,7 +144,7 @@ func TestDoRequestNewWayObj(t *testing.T) {
|
|||||||
|
|
||||||
func TestDoRequestNewWayFile(t *testing.T) {
|
func TestDoRequestNewWayFile(t *testing.T) {
|
||||||
reqObj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
reqObj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
reqBodyExpected, err := runtime.Encode(reqObj)
|
reqBodyExpected, err := runtime.DefaultCodec.Encode(reqObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ func TestDoRequestNewWayFile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expectedObj := &api.Service{Port: 12345}
|
expectedObj := &api.Service{Port: 12345}
|
||||||
expectedBody, _ := runtime.Encode(expectedObj)
|
expectedBody, _ := runtime.DefaultCodec.Encode(expectedObj)
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(expectedBody),
|
ResponseBody: string(expectedBody),
|
||||||
@@ -285,7 +285,7 @@ func TestSetPollPeriod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPolling(t *testing.T) {
|
func TestPolling(t *testing.T) {
|
||||||
objects := []interface{}{
|
objects := []runtime.Object{
|
||||||
&api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}},
|
&api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}},
|
||||||
&api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}},
|
&api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}},
|
||||||
&api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}},
|
&api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}},
|
||||||
@@ -295,7 +295,7 @@ func TestPolling(t *testing.T) {
|
|||||||
|
|
||||||
callNumber := 0
|
callNumber := 0
|
||||||
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
data, err := runtime.Encode(objects[callNumber])
|
data, err := runtime.DefaultCodec.Encode(objects[callNumber])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected encode error")
|
t.Errorf("Unexpected encode error")
|
||||||
}
|
}
|
||||||
@@ -380,7 +380,7 @@ func checkAuth(t *testing.T, expect AuthInfo, r *http.Request) {
|
|||||||
func TestWatch(t *testing.T) {
|
func TestWatch(t *testing.T) {
|
||||||
var table = []struct {
|
var table = []struct {
|
||||||
t watch.EventType
|
t watch.EventType
|
||||||
obj interface{}
|
obj runtime.Object
|
||||||
}{
|
}{
|
||||||
{watch.Added, &api.Pod{JSONBase: api.JSONBase{ID: "first"}}},
|
{watch.Added, &api.Pod{JSONBase: api.JSONBase{ID: "first"}}},
|
||||||
{watch.Modified, &api.Pod{JSONBase: api.JSONBase{ID: "second"}}},
|
{watch.Modified, &api.Pod{JSONBase: api.JSONBase{ID: "second"}}},
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ func (r RealPodControl) createReplica(controllerSpec api.ReplicationController)
|
|||||||
if labels != nil {
|
if labels != nil {
|
||||||
labels["replicationController"] = controllerSpec.ID
|
labels["replicationController"] = controllerSpec.ID
|
||||||
}
|
}
|
||||||
pod := api.Pod{
|
pod := &api.Pod{
|
||||||
DesiredState: controllerSpec.DesiredState.PodTemplate.DesiredState,
|
DesiredState: controllerSpec.DesiredState.PodTemplate.DesiredState,
|
||||||
Labels: controllerSpec.DesiredState.PodTemplate.Labels,
|
Labels: controllerSpec.DesiredState.PodTemplate.Labels,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ func newReplicationController(replicas int) api.ReplicationController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPodList(count int) api.PodList {
|
func newPodList(count int) *api.PodList {
|
||||||
pods := []api.Pod{}
|
pods := []api.Pod{}
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
pods = append(pods, api.Pod{
|
pods = append(pods, api.Pod{
|
||||||
@@ -94,7 +94,7 @@ func newPodList(count int) api.PodList {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return api.PodList{
|
return &api.PodList{
|
||||||
Items: pods,
|
Items: pods,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ func validateSyncReplication(t *testing.T, fakePodControl *FakePodControl, expec
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncReplicationControllerDoesNothing(t *testing.T) {
|
func TestSyncReplicationControllerDoesNothing(t *testing.T) {
|
||||||
body, _ := runtime.Encode(newPodList(2))
|
body, _ := runtime.DefaultCodec.Encode(newPodList(2))
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(body),
|
ResponseBody: string(body),
|
||||||
@@ -129,7 +129,7 @@ func TestSyncReplicationControllerDoesNothing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncReplicationControllerDeletes(t *testing.T) {
|
func TestSyncReplicationControllerDeletes(t *testing.T) {
|
||||||
body, _ := runtime.Encode(newPodList(2))
|
body, _ := runtime.DefaultCodec.Encode(newPodList(2))
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(body),
|
ResponseBody: string(body),
|
||||||
@@ -149,7 +149,7 @@ func TestSyncReplicationControllerDeletes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncReplicationControllerCreates(t *testing.T) {
|
func TestSyncReplicationControllerCreates(t *testing.T) {
|
||||||
body, _ := runtime.Encode(newPodList(0))
|
body, _ := runtime.DefaultCodec.Encode(newPodList(0))
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(body),
|
ResponseBody: string(body),
|
||||||
@@ -169,7 +169,7 @@ func TestSyncReplicationControllerCreates(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateReplica(t *testing.T) {
|
func TestCreateReplica(t *testing.T) {
|
||||||
body, _ := runtime.Encode(api.Pod{})
|
body, _ := runtime.DefaultCodec.Encode(&api.Pod{})
|
||||||
fakeHandler := util.FakeHandler{
|
fakeHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: string(body),
|
ResponseBody: string(body),
|
||||||
@@ -292,7 +292,7 @@ func TestSyncronize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fakeControllerHandler := util.FakeHandler{
|
fakeControllerHandler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: runtime.EncodeOrDie(&api.ReplicationControllerList{
|
ResponseBody: runtime.DefaultScheme.EncodeOrDie(&api.ReplicationControllerList{
|
||||||
Items: []api.ReplicationController{
|
Items: []api.ReplicationController{
|
||||||
controllerSpec1,
|
controllerSpec1,
|
||||||
controllerSpec2,
|
controllerSpec2,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type Converter struct {
|
|||||||
// do the conversion.
|
// do the conversion.
|
||||||
funcs map[typePair]reflect.Value
|
funcs map[typePair]reflect.Value
|
||||||
|
|
||||||
// If true, print helpful debugging info. Quite verbose.
|
// If non-nil, will be called to print helpful debugging info. Quite verbose.
|
||||||
Debug DebugLogger
|
Debug DebugLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,29 +48,43 @@ func NewConverter() *Converter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scope is passed to conversion funcs to allow them to continue an ongoing conversion.
|
||||||
|
// If multiple converters exist in the system, Scope will allow you to use the correct one
|
||||||
|
// from a conversion function--that is, the one your conversion function was called by.
|
||||||
|
type Scope interface {
|
||||||
|
// Call Convert to convert sub-objects. Note that if you call it with your own exact
|
||||||
|
// parameters, you'll run out of stack space before anything useful happens.
|
||||||
|
Convert(src, dest interface{}, flags FieldMatchingFlags) error
|
||||||
|
}
|
||||||
|
|
||||||
// Register registers a conversion func with the Converter. conversionFunc must take
|
// Register registers a conversion func with the Converter. conversionFunc must take
|
||||||
// two parameters, the input and output type. It must take a pointer to each. It must
|
// three parameters: a pointer to the input type, a pointer to the output type, and
|
||||||
// return an error.
|
// a conversion.Scope (which should be used if recursive conversion calls are desired).
|
||||||
|
// It must return an error.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// c.Register(func(in *Pod, out *v1beta1.Pod) error { ... return nil })
|
// c.Register(func(in *Pod, out *v1beta1.Pod, s Scope) error { ... return nil })
|
||||||
func (c *Converter) Register(conversionFunc interface{}) error {
|
func (c *Converter) Register(conversionFunc interface{}) error {
|
||||||
fv := reflect.ValueOf(conversionFunc)
|
fv := reflect.ValueOf(conversionFunc)
|
||||||
ft := fv.Type()
|
ft := fv.Type()
|
||||||
if ft.Kind() != reflect.Func {
|
if ft.Kind() != reflect.Func {
|
||||||
return fmt.Errorf("expected func, got: %v", ft)
|
return fmt.Errorf("expected func, got: %v", ft)
|
||||||
}
|
}
|
||||||
if ft.NumIn() != 2 {
|
if ft.NumIn() != 3 {
|
||||||
return fmt.Errorf("expected two in params, got: %v", ft)
|
return fmt.Errorf("expected three 'in' params, got: %v", ft)
|
||||||
}
|
}
|
||||||
if ft.NumOut() != 1 {
|
if ft.NumOut() != 1 {
|
||||||
return fmt.Errorf("expected one out param, got: %v", ft)
|
return fmt.Errorf("expected one 'out' param, got: %v", ft)
|
||||||
}
|
}
|
||||||
if ft.In(0).Kind() != reflect.Ptr {
|
if ft.In(0).Kind() != reflect.Ptr {
|
||||||
return fmt.Errorf("expected pointer arg for in param 0, got: %v", ft)
|
return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
|
||||||
}
|
}
|
||||||
if ft.In(1).Kind() != reflect.Ptr {
|
if ft.In(1).Kind() != reflect.Ptr {
|
||||||
return fmt.Errorf("expected pointer arg for in param 1, got: %v", ft)
|
return fmt.Errorf("expected pointer arg for 'in' param 1, got: %v", ft)
|
||||||
|
}
|
||||||
|
scopeType := Scope(c)
|
||||||
|
if e, a := reflect.TypeOf(&scopeType).Elem(), ft.In(2); e != a {
|
||||||
|
return fmt.Errorf("expected '%v' arg for 'in' param 2, got '%v' (%v)", e, a, ft)
|
||||||
}
|
}
|
||||||
var forErrorType error
|
var forErrorType error
|
||||||
// This convolution is necessary, otherwise TypeOf picks up on the fact
|
// This convolution is necessary, otherwise TypeOf picks up on the fact
|
||||||
@@ -138,7 +152,8 @@ func (c *Converter) convert(sv, dv reflect.Value, flags FieldMatchingFlags) erro
|
|||||||
if c.Debug != nil {
|
if c.Debug != nil {
|
||||||
c.Debug.Logf("Calling custom conversion of '%v' to '%v'", st, dt)
|
c.Debug.Logf("Calling custom conversion of '%v' to '%v'", st, dt)
|
||||||
}
|
}
|
||||||
ret := fv.Call([]reflect.Value{sv.Addr(), dv.Addr()})[0].Interface()
|
args := []reflect.Value{sv.Addr(), dv.Addr(), reflect.ValueOf(Scope(c))}
|
||||||
|
ret := fv.Call(args)[0].Interface()
|
||||||
// This convolution is necssary because nil interfaces won't convert
|
// This convolution is necssary because nil interfaces won't convert
|
||||||
// to errors.
|
// to errors.
|
||||||
if ret == nil {
|
if ret == nil {
|
||||||
|
|||||||
@@ -27,28 +27,30 @@ import (
|
|||||||
func TestConverter_CallsRegisteredFunctions(t *testing.T) {
|
func TestConverter_CallsRegisteredFunctions(t *testing.T) {
|
||||||
type A struct {
|
type A struct {
|
||||||
Foo string
|
Foo string
|
||||||
|
Baz int
|
||||||
}
|
}
|
||||||
type B struct {
|
type B struct {
|
||||||
Bar string
|
Bar string
|
||||||
|
Baz int
|
||||||
}
|
}
|
||||||
type C struct{}
|
type C struct{}
|
||||||
c := NewConverter()
|
c := NewConverter()
|
||||||
err := c.Register(func(in *A, out *B) error {
|
err := c.Register(func(in *A, out *B, s Scope) error {
|
||||||
out.Bar = in.Foo
|
out.Bar = in.Foo
|
||||||
return nil
|
return s.Convert(&in.Baz, &out.Baz, 0)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error %v", err)
|
t.Fatalf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
err = c.Register(func(in *B, out *A) error {
|
err = c.Register(func(in *B, out *A, s Scope) error {
|
||||||
out.Foo = in.Bar
|
out.Foo = in.Bar
|
||||||
return nil
|
return s.Convert(&in.Baz, &out.Baz, 0)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error %v", err)
|
t.Fatalf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
x := A{"hello, intrepid test reader!"}
|
x := A{"hello, intrepid test reader!", 3}
|
||||||
y := B{}
|
y := B{}
|
||||||
|
|
||||||
err = c.Convert(&x, &y, 0)
|
err = c.Convert(&x, &y, 0)
|
||||||
@@ -58,8 +60,11 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
|
|||||||
if e, a := x.Foo, y.Bar; e != a {
|
if e, a := x.Foo, y.Bar; e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
|
if e, a := x.Baz, y.Baz; e != a {
|
||||||
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
z := B{"all your test are belong to us"}
|
z := B{"all your test are belong to us", 42}
|
||||||
w := A{}
|
w := A{}
|
||||||
|
|
||||||
err = c.Convert(&z, &w, 0)
|
err = c.Convert(&z, &w, 0)
|
||||||
@@ -69,8 +74,11 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
|
|||||||
if e, a := z.Bar, w.Foo; e != a {
|
if e, a := z.Bar, w.Foo; e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
|
if e, a := z.Baz, w.Baz; e != a {
|
||||||
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
err = c.Register(func(in *A, out *C) error {
|
err = c.Register(func(in *A, out *C, s Scope) error {
|
||||||
return fmt.Errorf("C can't store an A, silly")
|
return fmt.Errorf("C can't store an A, silly")
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -85,7 +93,7 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
|
|||||||
|
|
||||||
func TestConverter_fuzz(t *testing.T) {
|
func TestConverter_fuzz(t *testing.T) {
|
||||||
newAnonType := func() interface{} {
|
newAnonType := func() interface{} {
|
||||||
return reflect.New(reflect.TypeOf(externalTypeReturn())).Interface()
|
return reflect.New(reflect.TypeOf(externalTypeReturn()).Elem()).Interface()
|
||||||
}
|
}
|
||||||
// Use the same types from the scheme test.
|
// Use the same types from the scheme test.
|
||||||
table := []struct {
|
table := []struct {
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ func NewScheme() *Scheme {
|
|||||||
|
|
||||||
// AddKnownTypes registers all types passed in 'types' as being members of version 'version.
|
// AddKnownTypes registers all types passed in 'types' as being members of version 'version.
|
||||||
// Encode() will refuse objects unless their type has been registered with AddKnownTypes.
|
// Encode() will refuse objects unless their type has been registered with AddKnownTypes.
|
||||||
// All objects passed to types should be structs, not pointers to structs. The name that go
|
// All objects passed to types should be pointers to structs. The name that go reports for
|
||||||
// reports for the struct becomes the "kind" field when encoding.
|
// the struct becomes the "kind" field when encoding.
|
||||||
func (s *Scheme) AddKnownTypes(version string, types ...interface{}) {
|
func (s *Scheme) AddKnownTypes(version string, types ...interface{}) {
|
||||||
knownTypes, found := s.versionMap[version]
|
knownTypes, found := s.versionMap[version]
|
||||||
if !found {
|
if !found {
|
||||||
@@ -95,8 +95,12 @@ func (s *Scheme) AddKnownTypes(version string, types ...interface{}) {
|
|||||||
}
|
}
|
||||||
for _, obj := range types {
|
for _, obj := range types {
|
||||||
t := reflect.TypeOf(obj)
|
t := reflect.TypeOf(obj)
|
||||||
|
if t.Kind() != reflect.Ptr {
|
||||||
|
panic("All types must be pointers to structs.")
|
||||||
|
}
|
||||||
|
t = t.Elem()
|
||||||
if t.Kind() != reflect.Struct {
|
if t.Kind() != reflect.Struct {
|
||||||
panic("All types must be structs.")
|
panic("All types must be pointers to structs.")
|
||||||
}
|
}
|
||||||
knownTypes[t.Name()] = t
|
knownTypes[t.Name()] = t
|
||||||
s.typeToVersion[t] = version
|
s.typeToVersion[t] = version
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func externalTypeReturn() interface{} {
|
|||||||
O *TestType2 `yaml:"O,omitempty" json:"O,omitempty"`
|
O *TestType2 `yaml:"O,omitempty" json:"O,omitempty"`
|
||||||
P []TestType2 `yaml:"Q,omitempty" json:"Q,omitempty"`
|
P []TestType2 `yaml:"Q,omitempty" json:"Q,omitempty"`
|
||||||
}
|
}
|
||||||
return TestType1{}
|
return &TestType1{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExternalInternalSame struct {
|
type ExternalInternalSame struct {
|
||||||
@@ -124,8 +124,8 @@ var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
|
|||||||
// Returns a new Scheme set up with the test objects.
|
// Returns a new Scheme set up with the test objects.
|
||||||
func GetTestScheme() *Scheme {
|
func GetTestScheme() *Scheme {
|
||||||
s := NewScheme()
|
s := NewScheme()
|
||||||
s.AddKnownTypes("", TestType1{}, ExternalInternalSame{})
|
s.AddKnownTypes("", &TestType1{}, &ExternalInternalSame{})
|
||||||
s.AddKnownTypes("v1", externalTypeReturn(), ExternalInternalSame{})
|
s.AddKnownTypes("v1", externalTypeReturn(), &ExternalInternalSame{})
|
||||||
s.ExternalVersion = "v1"
|
s.ExternalVersion = "v1"
|
||||||
s.InternalVersion = ""
|
s.InternalVersion = ""
|
||||||
s.MetaInsertionFactory = testMetaInsertionFactory{}
|
s.MetaInsertionFactory = testMetaInsertionFactory{}
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ import (
|
|||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Master is used to announce the current elected master.
|
||||||
|
type Master string
|
||||||
|
|
||||||
|
// IsAnAPIObject is used solely so we can work with the watch package.
|
||||||
|
// TODO: Either fix watch so this isn't necessary, or make this a real API Object.
|
||||||
|
// TODO: when it becomes clear how this package will be used, move these declarations to
|
||||||
|
// to the proper place.
|
||||||
|
func (Master) IsAnAPIObject() {}
|
||||||
|
|
||||||
// NewEtcdMasterElector returns an implementation of election.MasterElector backed by etcd.
|
// NewEtcdMasterElector returns an implementation of election.MasterElector backed by etcd.
|
||||||
func NewEtcdMasterElector(h tools.EtcdGetSet) MasterElector {
|
func NewEtcdMasterElector(h tools.EtcdGetSet) MasterElector {
|
||||||
return &etcdMasterElector{etcd: h}
|
return &etcdMasterElector{etcd: h}
|
||||||
@@ -58,7 +67,7 @@ func (e *etcdMasterElector) run(path, id string) {
|
|||||||
case m := <-masters:
|
case m := <-masters:
|
||||||
e.events <- watch.Event{
|
e.events <- watch.Event{
|
||||||
Type: watch.Modified,
|
Type: watch.Modified,
|
||||||
Object: m,
|
Object: Master(m),
|
||||||
}
|
}
|
||||||
case e := <-errors:
|
case e := <-errors:
|
||||||
glog.Errorf("error in election: %v", e)
|
glog.Errorf("error in election: %v", e)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func TestEtcdMasterOther(t *testing.T) {
|
|||||||
master := NewEtcdMasterElector(etcd)
|
master := NewEtcdMasterElector(etcd)
|
||||||
w := master.Elect(path, "bar")
|
w := master.Elect(path, "bar")
|
||||||
result := <-w.ResultChan()
|
result := <-w.ResultChan()
|
||||||
if result.Type != watch.Modified || result.Object.(string) != "baz" {
|
if result.Type != watch.Modified || result.Object.(Master) != "baz" {
|
||||||
t.Errorf("unexpected event: %#v", result)
|
t.Errorf("unexpected event: %#v", result)
|
||||||
}
|
}
|
||||||
w.Stop()
|
w.Stop()
|
||||||
@@ -52,7 +52,7 @@ func TestEtcdMasterNoOther(t *testing.T) {
|
|||||||
master := NewEtcdMasterElector(e)
|
master := NewEtcdMasterElector(e)
|
||||||
w := master.Elect(path, "bar")
|
w := master.Elect(path, "bar")
|
||||||
result := <-w.ResultChan()
|
result := <-w.ResultChan()
|
||||||
if result.Type != watch.Modified || result.Object.(string) != "bar" {
|
if result.Type != watch.Modified || result.Object.(Master) != "bar" {
|
||||||
t.Errorf("unexpected event: %#v", result)
|
t.Errorf("unexpected event: %#v", result)
|
||||||
}
|
}
|
||||||
w.Stop()
|
w.Stop()
|
||||||
@@ -91,7 +91,7 @@ func TestEtcdMasterNoOtherThenConflict(t *testing.T) {
|
|||||||
master := NewEtcdMasterElector(e)
|
master := NewEtcdMasterElector(e)
|
||||||
w := master.Elect(path, "bar")
|
w := master.Elect(path, "bar")
|
||||||
result := <-w.ResultChan()
|
result := <-w.ResultChan()
|
||||||
if result.Type != watch.Modified || result.Object.(string) != "bar" {
|
if result.Type != watch.Modified || result.Object.(Master) != "bar" {
|
||||||
t.Errorf("unexpected event: %#v", result)
|
t.Errorf("unexpected event: %#v", result)
|
||||||
}
|
}
|
||||||
w.Stop()
|
w.Stop()
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ func portsFromString(spec string) []api.Port {
|
|||||||
|
|
||||||
// RunController creates a new replication controller named 'name' which creates 'replicas' pods running 'image'.
|
// RunController creates a new replication controller named 'name' which creates 'replicas' pods running 'image'.
|
||||||
func RunController(image, name string, replicas int, client client.Interface, portSpec string, servicePort int) error {
|
func RunController(image, name string, replicas int, client client.Interface, portSpec string, servicePort int) error {
|
||||||
controller := api.ReplicationController{
|
controller := &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: name,
|
ID: name,
|
||||||
},
|
},
|
||||||
@@ -227,8 +227,8 @@ func RunController(image, name string, replicas int, client client.Interface, po
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createService(name string, port int, client client.Interface) (api.Service, error) {
|
func createService(name string, port int, client client.Interface) (*api.Service, error) {
|
||||||
svc := api.Service{
|
svc := &api.Service{
|
||||||
JSONBase: api.JSONBase{ID: name},
|
JSONBase: api.JSONBase{ID: name},
|
||||||
Port: port,
|
Port: port,
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func TestUpdateWithPods(t *testing.T) {
|
|||||||
}
|
}
|
||||||
Update("foo", &fakeClient, 0, "")
|
Update("foo", &fakeClient, 0, "")
|
||||||
if len(fakeClient.Actions) != 5 {
|
if len(fakeClient.Actions) != 5 {
|
||||||
t.Errorf("Unexpected action list %#v", fakeClient.Actions)
|
t.Fatalf("Unexpected action list %#v", fakeClient.Actions)
|
||||||
}
|
}
|
||||||
validateAction(client.FakeAction{Action: "get-controller", Value: "foo"}, fakeClient.Actions[0], t)
|
validateAction(client.FakeAction{Action: "get-controller", Value: "foo"}, fakeClient.Actions[0], t)
|
||||||
validateAction(client.FakeAction{Action: "list-pods"}, fakeClient.Actions[1], t)
|
validateAction(client.FakeAction{Action: "list-pods"}, fakeClient.Actions[1], t)
|
||||||
@@ -94,7 +94,7 @@ func TestUpdateWithNewImage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
validateAction(client.FakeAction{Action: "get-controller", Value: "foo"}, fakeClient.Actions[0], t)
|
validateAction(client.FakeAction{Action: "get-controller", Value: "foo"}, fakeClient.Actions[0], t)
|
||||||
|
|
||||||
newCtrl := *runtime.CopyOrDie(fakeClient.Ctrl).(*api.ReplicationController)
|
newCtrl := runtime.DefaultScheme.CopyOrDie(&fakeClient.Ctrl).(*api.ReplicationController)
|
||||||
newCtrl.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image = "fooImage:2"
|
newCtrl.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image = "fooImage:2"
|
||||||
validateAction(client.FakeAction{Action: "update-controller", Value: newCtrl}, fakeClient.Actions[1], t)
|
validateAction(client.FakeAction{Action: "update-controller", Value: newCtrl}, fakeClient.Actions[1], t)
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ func TestRunController(t *testing.T) {
|
|||||||
if len(fakeClient.Actions) != 1 || fakeClient.Actions[0].Action != "create-controller" {
|
if len(fakeClient.Actions) != 1 || fakeClient.Actions[0].Action != "create-controller" {
|
||||||
t.Errorf("Unexpected actions: %#v", fakeClient.Actions)
|
t.Errorf("Unexpected actions: %#v", fakeClient.Actions)
|
||||||
}
|
}
|
||||||
controller := fakeClient.Actions[0].Value.(api.ReplicationController)
|
controller := fakeClient.Actions[0].Value.(*api.ReplicationController)
|
||||||
if controller.ID != name ||
|
if controller.ID != name ||
|
||||||
controller.DesiredState.Replicas != replicas ||
|
controller.DesiredState.Replicas != replicas ||
|
||||||
controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image != image {
|
controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image != image {
|
||||||
@@ -133,7 +133,7 @@ func TestRunControllerWithService(t *testing.T) {
|
|||||||
fakeClient.Actions[1].Action != "create-service" {
|
fakeClient.Actions[1].Action != "create-service" {
|
||||||
t.Errorf("Unexpected actions: %#v", fakeClient.Actions)
|
t.Errorf("Unexpected actions: %#v", fakeClient.Actions)
|
||||||
}
|
}
|
||||||
controller := fakeClient.Actions[0].Value.(api.ReplicationController)
|
controller := fakeClient.Actions[0].Value.(*api.ReplicationController)
|
||||||
if controller.ID != name ||
|
if controller.ID != name ||
|
||||||
controller.DesiredState.Replicas != replicas ||
|
controller.DesiredState.Replicas != replicas ||
|
||||||
controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image != image {
|
controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image != image {
|
||||||
@@ -152,7 +152,7 @@ func TestStopController(t *testing.T) {
|
|||||||
fakeClient.Actions[0].Value.(string) != name {
|
fakeClient.Actions[0].Value.(string) != name {
|
||||||
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[0])
|
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[0])
|
||||||
}
|
}
|
||||||
controller := fakeClient.Actions[1].Value.(api.ReplicationController)
|
controller := fakeClient.Actions[1].Value.(*api.ReplicationController)
|
||||||
if fakeClient.Actions[1].Action != "update-controller" ||
|
if fakeClient.Actions[1].Action != "update-controller" ||
|
||||||
controller.DesiredState.Replicas != 0 {
|
controller.DesiredState.Replicas != 0 {
|
||||||
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[1])
|
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[1])
|
||||||
@@ -171,7 +171,7 @@ func TestResizeController(t *testing.T) {
|
|||||||
fakeClient.Actions[0].Value.(string) != name {
|
fakeClient.Actions[0].Value.(string) != name {
|
||||||
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[0])
|
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[0])
|
||||||
}
|
}
|
||||||
controller := fakeClient.Actions[1].Value.(api.ReplicationController)
|
controller := fakeClient.Actions[1].Value.(*api.ReplicationController)
|
||||||
if fakeClient.Actions[1].Action != "update-controller" ||
|
if fakeClient.Actions[1].Action != "update-controller" ||
|
||||||
controller.DesiredState.Replicas != 17 {
|
controller.DesiredState.Replicas != 17 {
|
||||||
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[1])
|
t.Errorf("Unexpected Action: %#v", fakeClient.Actions[1])
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ type Parser struct {
|
|||||||
storageToType map[string]reflect.Type
|
storageToType map[string]reflect.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewParser(objectMap map[string]interface{}) *Parser {
|
// NewParser creates a new parser.
|
||||||
|
func NewParser(objectMap map[string]runtime.Object) *Parser {
|
||||||
typeMap := make(map[string]reflect.Type)
|
typeMap := make(map[string]reflect.Type)
|
||||||
for name, obj := range objectMap {
|
for name, obj := range objectMap {
|
||||||
typeMap[name] = reflect.TypeOf(obj)
|
typeMap[name] = reflect.TypeOf(obj).Elem()
|
||||||
}
|
}
|
||||||
return &Parser{typeMap}
|
return &Parser{typeMap}
|
||||||
}
|
}
|
||||||
@@ -43,12 +44,12 @@ func (p *Parser) ToWireFormat(data []byte, storage string) ([]byte, error) {
|
|||||||
return nil, fmt.Errorf("unknown storage type: %v", storage)
|
return nil, fmt.Errorf("unknown storage type: %v", storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := reflect.New(prototypeType).Interface()
|
obj := reflect.New(prototypeType).Interface().(runtime.Object)
|
||||||
err := runtime.DecodeInto(data, obj)
|
err := runtime.DefaultCodec.DecodeInto(data, obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return runtime.Encode(obj)
|
return runtime.DefaultCodec.Encode(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) SupportedWireStorage() []string {
|
func (p *Parser) SupportedWireStorage() []string {
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestParseBadStorage(t *testing.T) {
|
func TestParseBadStorage(t *testing.T) {
|
||||||
p := NewParser(map[string]interface{}{})
|
p := NewParser(map[string]runtime.Object{})
|
||||||
_, err := p.ToWireFormat([]byte("{}"), "badstorage")
|
_, err := p.ToWireFormat([]byte("{}"), "badstorage")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error, received none")
|
t.Errorf("Expected error, received none")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoParseTest(t *testing.T, storage string, obj interface{}, p *Parser) {
|
func DoParseTest(t *testing.T, storage string, obj runtime.Object, p *Parser) {
|
||||||
jsonData, _ := runtime.Encode(obj)
|
jsonData, _ := runtime.DefaultCodec.Encode(obj)
|
||||||
yamlData, _ := yaml.Marshal(obj)
|
yamlData, _ := yaml.Marshal(obj)
|
||||||
t.Logf("Intermediate yaml:\n%v\n", string(yamlData))
|
t.Logf("Intermediate yaml:\n%v\n", string(yamlData))
|
||||||
t.Logf("Intermediate json:\n%v\n", string(jsonData))
|
t.Logf("Intermediate json:\n%v\n", string(jsonData))
|
||||||
@@ -56,14 +56,14 @@ func DoParseTest(t *testing.T, storage string, obj interface{}, p *Parser) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var testParser = NewParser(map[string]interface{}{
|
var testParser = NewParser(map[string]runtime.Object{
|
||||||
"pods": api.Pod{},
|
"pods": &api.Pod{},
|
||||||
"services": api.Service{},
|
"services": &api.Service{},
|
||||||
"replicationControllers": api.ReplicationController{},
|
"replicationControllers": &api.ReplicationController{},
|
||||||
})
|
})
|
||||||
|
|
||||||
func TestParsePod(t *testing.T) {
|
func TestParsePod(t *testing.T) {
|
||||||
DoParseTest(t, "pods", api.Pod{
|
DoParseTest(t, "pods", &api.Pod{
|
||||||
JSONBase: api.JSONBase{APIVersion: "v1beta1", ID: "test pod", Kind: "Pod"},
|
JSONBase: api.JSONBase{APIVersion: "v1beta1", ID: "test pod", Kind: "Pod"},
|
||||||
DesiredState: api.PodState{
|
DesiredState: api.PodState{
|
||||||
Manifest: api.ContainerManifest{
|
Manifest: api.ContainerManifest{
|
||||||
@@ -80,7 +80,7 @@ func TestParsePod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseService(t *testing.T) {
|
func TestParseService(t *testing.T) {
|
||||||
DoParseTest(t, "services", api.Service{
|
DoParseTest(t, "services", &api.Service{
|
||||||
JSONBase: api.JSONBase{APIVersion: "v1beta1", ID: "my service", Kind: "Service"},
|
JSONBase: api.JSONBase{APIVersion: "v1beta1", ID: "my service", Kind: "Service"},
|
||||||
Port: 8080,
|
Port: 8080,
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
@@ -93,7 +93,7 @@ func TestParseService(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseController(t *testing.T) {
|
func TestParseController(t *testing.T) {
|
||||||
DoParseTest(t, "replicationControllers", api.ReplicationController{
|
DoParseTest(t, "replicationControllers", &api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{APIVersion: "v1beta1", ID: "my controller", Kind: "ReplicationController"},
|
JSONBase: api.JSONBase{APIVersion: "v1beta1", ID: "my controller", Kind: "ReplicationController"},
|
||||||
DesiredState: api.ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
Replicas: 9001,
|
Replicas: 9001,
|
||||||
@@ -119,13 +119,15 @@ type TestParseType struct {
|
|||||||
Data string `json:"data" yaml:"data"`
|
Data string `json:"data" yaml:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*TestParseType) IsAnAPIObject() {}
|
||||||
|
|
||||||
func TestParseCustomType(t *testing.T) {
|
func TestParseCustomType(t *testing.T) {
|
||||||
runtime.AddKnownTypes("", TestParseType{})
|
runtime.DefaultScheme.AddKnownTypes("", &TestParseType{})
|
||||||
runtime.AddKnownTypes("v1beta1", TestParseType{})
|
runtime.DefaultScheme.AddKnownTypes("v1beta1", &TestParseType{})
|
||||||
parser := NewParser(map[string]interface{}{
|
parser := NewParser(map[string]runtime.Object{
|
||||||
"custom": TestParseType{},
|
"custom": &TestParseType{},
|
||||||
})
|
})
|
||||||
DoParseTest(t, "custom", TestParseType{
|
DoParseTest(t, "custom", &TestParseType{
|
||||||
JSONBase: api.JSONBase{APIVersion: "", ID: "my custom object", Kind: "TestParseType"},
|
JSONBase: api.JSONBase{APIVersion: "", ID: "my custom object", Kind: "TestParseType"},
|
||||||
Data: "test data",
|
Data: "test data",
|
||||||
}, parser)
|
}, parser)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func (s *ProxyServer) Serve() error {
|
|||||||
func (s *ProxyServer) doError(w http.ResponseWriter, err error) {
|
func (s *ProxyServer) doError(w http.ResponseWriter, err error) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Header().Add("Content-type", "application/json")
|
w.Header().Add("Content-type", "application/json")
|
||||||
data, _ := runtime.Encode(api.Status{
|
data, _ := runtime.DefaultCodec.Encode(&api.Status{
|
||||||
Status: api.StatusFailure,
|
Status: api.StatusFailure,
|
||||||
Message: fmt.Sprintf("internal error: %#v", err),
|
Message: fmt.Sprintf("internal error: %#v", err),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import (
|
|||||||
type ResourcePrinter interface {
|
type ResourcePrinter interface {
|
||||||
// Print receives an arbitrary JSON body, formats it and prints it to a writer.
|
// Print receives an arbitrary JSON body, formats it and prints it to a writer.
|
||||||
Print([]byte, io.Writer) error
|
Print([]byte, io.Writer) error
|
||||||
PrintObj(interface{}, io.Writer) error
|
PrintObj(runtime.Object, io.Writer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// IdentityPrinter is an implementation of ResourcePrinter which simply copies the body out to the output stream.
|
// IdentityPrinter is an implementation of ResourcePrinter which simply copies the body out to the output stream.
|
||||||
@@ -49,8 +49,8 @@ func (i *IdentityPrinter) Print(data []byte, w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrintObj is an implementation of ResourcePrinter.PrintObj which simply writes the object to the Writer.
|
// PrintObj is an implementation of ResourcePrinter.PrintObj which simply writes the object to the Writer.
|
||||||
func (i *IdentityPrinter) PrintObj(obj interface{}, output io.Writer) error {
|
func (i *IdentityPrinter) PrintObj(obj runtime.Object, output io.Writer) error {
|
||||||
data, err := runtime.Encode(obj)
|
data, err := runtime.DefaultCodec.Encode(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ func (y *YAMLPrinter) Print(data []byte, w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrintObj prints the data as YAML.
|
// PrintObj prints the data as YAML.
|
||||||
func (y *YAMLPrinter) PrintObj(obj interface{}, w io.Writer) error {
|
func (y *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||||
output, err := yaml.Marshal(obj)
|
output, err := yaml.Marshal(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -251,7 +251,7 @@ func printStatus(status *api.Status, w io.Writer) error {
|
|||||||
// Print parses the data as JSON, then prints the parsed data in a human-friendly
|
// Print parses the data as JSON, then prints the parsed data in a human-friendly
|
||||||
// format according to the type of the data.
|
// format according to the type of the data.
|
||||||
func (h *HumanReadablePrinter) Print(data []byte, output io.Writer) error {
|
func (h *HumanReadablePrinter) Print(data []byte, output io.Writer) error {
|
||||||
var mapObj map[string]interface{}
|
var mapObj map[string]runtime.Object
|
||||||
if err := json.Unmarshal([]byte(data), &mapObj); err != nil {
|
if err := json.Unmarshal([]byte(data), &mapObj); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ func (h *HumanReadablePrinter) Print(data []byte, output io.Writer) error {
|
|||||||
return fmt.Errorf("unexpected object with no 'kind' field: %s", data)
|
return fmt.Errorf("unexpected object with no 'kind' field: %s", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := runtime.Decode(data)
|
obj, err := runtime.DefaultCodec.Decode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ func (h *HumanReadablePrinter) Print(data []byte, output io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
|
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
|
||||||
func (h *HumanReadablePrinter) PrintObj(obj interface{}, output io.Writer) error {
|
func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error {
|
||||||
w := tabwriter.NewWriter(output, 20, 5, 3, ' ', 0)
|
w := tabwriter.NewWriter(output, 20, 5, 3, ' ', 0)
|
||||||
defer w.Flush()
|
defer w.Flush()
|
||||||
if handler := h.handlerMap[reflect.TypeOf(obj)]; handler != nil {
|
if handler := h.handlerMap[reflect.TypeOf(obj)]; handler != nil {
|
||||||
@@ -292,7 +292,7 @@ type TemplatePrinter struct {
|
|||||||
|
|
||||||
// Print parses the data as JSON, and re-formats it with the Go Template.
|
// Print parses the data as JSON, and re-formats it with the Go Template.
|
||||||
func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
||||||
obj, err := runtime.Decode(data)
|
obj, err := runtime.DefaultCodec.Decode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -300,6 +300,6 @@ func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrintObj formats the obj with the Go Template.
|
// PrintObj formats the obj with the Go Template.
|
||||||
func (t *TemplatePrinter) PrintObj(obj interface{}, w io.Writer) error {
|
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||||
return t.Template.Execute(w, obj)
|
return t.Template.Execute(w, obj)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func TestYAMLPrinterPrint(t *testing.T) {
|
|||||||
t.Errorf("Test data and unmarshaled data are not equal: %#v vs %#v", poutput, testData)
|
t.Errorf("Test data and unmarshaled data are not equal: %#v vs %#v", poutput, testData)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := api.Pod{
|
obj := &api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
}
|
}
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
@@ -77,8 +77,8 @@ func TestYAMLPrinterPrint(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpeted error: %#v", err)
|
t.Errorf("Unexpeted error: %#v", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(obj, objOut) {
|
if !reflect.DeepEqual(obj, &objOut) {
|
||||||
t.Errorf("Unexpected inequality: %#v vs %#v", obj, objOut)
|
t.Errorf("Unexpected inequality: %#v vs %#v", obj, &objOut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,16 +91,16 @@ func TestIdentityPrinter(t *testing.T) {
|
|||||||
t.Errorf("Bytes are not equal: %s vs %s", str, buff.String())
|
t.Errorf("Bytes are not equal: %s vs %s", str, buff.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := api.Pod{
|
obj := &api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
}
|
}
|
||||||
buff.Reset()
|
buff.Reset()
|
||||||
printer.PrintObj(obj, buff)
|
printer.PrintObj(obj, buff)
|
||||||
objOut, err := runtime.Decode([]byte(buff.String()))
|
objOut, err := runtime.DefaultCodec.Decode([]byte(buff.String()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpeted error: %#v", err)
|
t.Errorf("Unexpeted error: %#v", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(&obj, objOut) {
|
if !reflect.DeepEqual(obj, objOut) {
|
||||||
t.Errorf("Unexpected inequality: %#v vs %#v", obj, objOut)
|
t.Errorf("Unexpected inequality: %#v vs %#v", obj, objOut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,8 +109,12 @@ type TestPrintType struct {
|
|||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*TestPrintType) IsAnAPIObject() {}
|
||||||
|
|
||||||
type TestUnknownType struct{}
|
type TestUnknownType struct{}
|
||||||
|
|
||||||
|
func (*TestUnknownType) IsAnAPIObject() {}
|
||||||
|
|
||||||
func PrintCustomType(obj *TestPrintType, w io.Writer) error {
|
func PrintCustomType(obj *TestPrintType, w io.Writer) error {
|
||||||
_, err := fmt.Fprintf(w, "%s", obj.Data)
|
_, err := fmt.Fprintf(w, "%s", obj.Data)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ type SourceEtcd struct {
|
|||||||
func NewSourceEtcd(key string, client tools.EtcdClient, updates chan<- interface{}) *SourceEtcd {
|
func NewSourceEtcd(key string, client tools.EtcdClient, updates chan<- interface{}) *SourceEtcd {
|
||||||
helper := tools.EtcdHelper{
|
helper := tools.EtcdHelper{
|
||||||
client,
|
client,
|
||||||
runtime.Codec,
|
runtime.DefaultCodec,
|
||||||
runtime.ResourceVersioner,
|
runtime.DefaultResourceVersioner,
|
||||||
}
|
}
|
||||||
source := &SourceEtcd{
|
source := &SourceEtcd{
|
||||||
key: key,
|
key: key,
|
||||||
|
|||||||
@@ -131,10 +131,10 @@ func (m *Master) init(cloud cloudprovider.Interface, podInfoGetter client.PodInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API_v1beta1 returns the resources and codec for API version v1beta1.
|
// API_v1beta1 returns the resources and codec for API version v1beta1.
|
||||||
func (m *Master) API_v1beta1() (map[string]apiserver.RESTStorage, apiserver.Codec) {
|
func (m *Master) API_v1beta1() (map[string]apiserver.RESTStorage, runtime.Codec) {
|
||||||
storage := make(map[string]apiserver.RESTStorage)
|
storage := make(map[string]apiserver.RESTStorage)
|
||||||
for k, v := range m.storage {
|
for k, v := range m.storage {
|
||||||
storage[k] = v
|
storage[k] = v
|
||||||
}
|
}
|
||||||
return storage, runtime.Codec
|
return storage, runtime.DefaultCodec
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ import (
|
|||||||
|
|
||||||
// Watcher is the interface needed to receive changes to services and endpoints.
|
// Watcher is the interface needed to receive changes to services and endpoints.
|
||||||
type Watcher interface {
|
type Watcher interface {
|
||||||
ListServices(label labels.Selector) (api.ServiceList, error)
|
ListServices(label labels.Selector) (*api.ServiceList, error)
|
||||||
ListEndpoints(label labels.Selector) (api.EndpointsList, error)
|
ListEndpoints(label labels.Selector) (*api.EndpointsList, error)
|
||||||
WatchServices(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchServices(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ func (s ConfigSourceEtcd) GetServices() ([]api.Service, []api.Endpoints, error)
|
|||||||
// and create a Service entry for it.
|
// and create a Service entry for it.
|
||||||
for i, node := range response.Node.Nodes {
|
for i, node := range response.Node.Nodes {
|
||||||
var svc api.Service
|
var svc api.Service
|
||||||
err = runtime.DecodeInto([]byte(node.Value), &svc)
|
err = runtime.DefaultCodec.DecodeInto([]byte(node.Value), &svc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Failed to load Service: %s (%#v)", node.Value, err)
|
glog.Errorf("Failed to load Service: %s (%#v)", node.Value, err)
|
||||||
continue
|
continue
|
||||||
@@ -166,7 +166,7 @@ func (s ConfigSourceEtcd) GetEndpoints(service string) (api.Endpoints, error) {
|
|||||||
}
|
}
|
||||||
// Parse all the endpoint specifications in this value.
|
// Parse all the endpoint specifications in this value.
|
||||||
var e api.Endpoints
|
var e api.Endpoints
|
||||||
err = runtime.DecodeInto([]byte(response.Node.Value), &e)
|
err = runtime.DefaultCodec.DecodeInto([]byte(response.Node.Value), &e)
|
||||||
return e, err
|
return e, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ func etcdResponseToService(response *etcd.Response) (*api.Service, error) {
|
|||||||
return nil, fmt.Errorf("invalid response from etcd: %#v", response)
|
return nil, fmt.Errorf("invalid response from etcd: %#v", response)
|
||||||
}
|
}
|
||||||
var svc api.Service
|
var svc api.Service
|
||||||
err := runtime.DecodeInto([]byte(response.Node.Value), &svc)
|
err := runtime.DefaultCodec.DecodeInto([]byte(response.Node.Value), &svc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,7 @@ func (s ConfigSourceEtcd) ProcessChange(response *etcd.Response) {
|
|||||||
func (s ConfigSourceEtcd) ProcessEndpointResponse(response *etcd.Response) {
|
func (s ConfigSourceEtcd) ProcessEndpointResponse(response *etcd.Response) {
|
||||||
glog.Infof("Processing a change in endpoint configuration... %s", *response)
|
glog.Infof("Processing a change in endpoint configuration... %s", *response)
|
||||||
var endpoints api.Endpoints
|
var endpoints api.Endpoints
|
||||||
err := runtime.DecodeInto([]byte(response.Node.Value), &endpoints)
|
err := runtime.DefaultCodec.DecodeInto([]byte(response.Node.Value), &endpoints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Failed to parse service out of etcd key: %v : %+v", response.Node.Value, err)
|
glog.Errorf("Failed to parse service out of etcd key: %v : %+v", response.Node.Value, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BindingStorage implements the RESTStorage interface. When bindings are written, it
|
// BindingStorage implements the RESTStorage interface. When bindings are written, it
|
||||||
@@ -40,32 +41,32 @@ func NewBindingStorage(bindingRegistry Registry) *BindingStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List returns an error because bindings are write-only objects.
|
// List returns an error because bindings are write-only objects.
|
||||||
func (*BindingStorage) List(selector labels.Selector) (interface{}, error) {
|
func (*BindingStorage) List(selector labels.Selector) (runtime.Object, error) {
|
||||||
return nil, errors.NewNotFound("binding", "list")
|
return nil, errors.NewNotFound("binding", "list")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns an error because bindings are write-only objects.
|
// Get returns an error because bindings are write-only objects.
|
||||||
func (*BindingStorage) Get(id string) (interface{}, error) {
|
func (*BindingStorage) Get(id string) (runtime.Object, error) {
|
||||||
return nil, errors.NewNotFound("binding", id)
|
return nil, errors.NewNotFound("binding", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete returns an error because bindings are write-only objects.
|
// Delete returns an error because bindings are write-only objects.
|
||||||
func (*BindingStorage) Delete(id string) (<-chan interface{}, error) {
|
func (*BindingStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
return nil, errors.NewNotFound("binding", id)
|
return nil, errors.NewNotFound("binding", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new binding object fit for having data unmarshalled into it.
|
// New returns a new binding object fit for having data unmarshalled into it.
|
||||||
func (*BindingStorage) New() interface{} {
|
func (*BindingStorage) New() runtime.Object {
|
||||||
return &api.Binding{}
|
return &api.Binding{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create attempts to make the assignment indicated by the binding it recieves.
|
// Create attempts to make the assignment indicated by the binding it recieves.
|
||||||
func (b *BindingStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (b *BindingStorage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
binding, ok := obj.(*api.Binding)
|
binding, ok := obj.(*api.Binding)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("incorrect type: %#v", obj)
|
return nil, fmt.Errorf("incorrect type: %#v", obj)
|
||||||
}
|
}
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
if err := b.registry.ApplyBinding(binding); err != nil {
|
if err := b.registry.ApplyBinding(binding); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -74,6 +75,6 @@ func (b *BindingStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update returns an error-- this object may not be updated.
|
// Update returns an error-- this object may not be updated.
|
||||||
func (b *BindingStorage) Update(obj interface{}) (<-chan interface{}, error) {
|
func (b *BindingStorage) Update(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
return nil, fmt.Errorf("Bindings may not be changed.")
|
return nil, fmt.Errorf("Bindings may not be changed.")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ func TestNewBindingStorage(t *testing.T) {
|
|||||||
PodID: "foo",
|
PodID: "foo",
|
||||||
Host: "bar",
|
Host: "bar",
|
||||||
}
|
}
|
||||||
body, err := runtime.Encode(binding)
|
body, err := runtime.DefaultCodec.Encode(binding)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected encode error %v", err)
|
t.Fatalf("Unexpected encode error %v", err)
|
||||||
}
|
}
|
||||||
obj := b.New()
|
obj := b.New()
|
||||||
err = runtime.DecodeInto(body, obj)
|
err = runtime.DefaultCodec.DecodeInto(body, obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type Registry interface {
|
|||||||
ListControllers() (*api.ReplicationControllerList, error)
|
ListControllers() (*api.ReplicationControllerList, error)
|
||||||
WatchControllers(resourceVersion uint64) (watch.Interface, error)
|
WatchControllers(resourceVersion uint64) (watch.Interface, error)
|
||||||
GetController(controllerID string) (*api.ReplicationController, error)
|
GetController(controllerID string) (*api.ReplicationController, error)
|
||||||
CreateController(controller api.ReplicationController) error
|
CreateController(controller *api.ReplicationController) error
|
||||||
UpdateController(controller api.ReplicationController) error
|
UpdateController(controller *api.ReplicationController) error
|
||||||
DeleteController(controllerID string) error
|
DeleteController(controllerID string) error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ func NewRegistryStorage(registry Registry, podRegistry pod.Registry) apiserver.R
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create registers the given ReplicationController.
|
// Create registers the given ReplicationController.
|
||||||
func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
controller, ok := obj.(*api.ReplicationController)
|
controller, ok := obj.(*api.ReplicationController)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("not a replication controller: %#v", obj)
|
return nil, fmt.Errorf("not a replication controller: %#v", obj)
|
||||||
@@ -67,8 +68,8 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
|
|
||||||
controller.CreationTimestamp = util.Now()
|
controller.CreationTimestamp = util.Now()
|
||||||
|
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
err := rs.registry.CreateController(*controller)
|
err := rs.registry.CreateController(controller)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -77,14 +78,14 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete asynchronously deletes the ReplicationController specified by its id.
|
// Delete asynchronously deletes the ReplicationController specified by its id.
|
||||||
func (rs *RegistryStorage) Delete(id string) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeleteController(id)
|
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeleteController(id)
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get obtains the ReplicationController specified by its id.
|
// Get obtains the ReplicationController specified by its id.
|
||||||
func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
func (rs *RegistryStorage) Get(id string) (runtime.Object, error) {
|
||||||
controller, err := rs.registry.GetController(id)
|
controller, err := rs.registry.GetController(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -93,7 +94,7 @@ func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List obtains a list of ReplicationControllers that match selector.
|
// List obtains a list of ReplicationControllers that match selector.
|
||||||
func (rs *RegistryStorage) List(selector labels.Selector) (interface{}, error) {
|
func (rs *RegistryStorage) List(selector labels.Selector) (runtime.Object, error) {
|
||||||
controllers, err := rs.registry.ListControllers()
|
controllers, err := rs.registry.ListControllers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -109,13 +110,13 @@ func (rs *RegistryStorage) List(selector labels.Selector) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ReplicationController for use with Create and Update.
|
// New creates a new ReplicationController for use with Create and Update.
|
||||||
func (rs RegistryStorage) New() interface{} {
|
func (rs RegistryStorage) New() runtime.Object {
|
||||||
return &api.ReplicationController{}
|
return &api.ReplicationController{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update replaces a given ReplicationController instance with an existing
|
// Update replaces a given ReplicationController instance with an existing
|
||||||
// instance in storage.registry.
|
// instance in storage.registry.
|
||||||
func (rs *RegistryStorage) Update(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Update(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
controller, ok := obj.(*api.ReplicationController)
|
controller, ok := obj.(*api.ReplicationController)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("not a replication controller: %#v", obj)
|
return nil, fmt.Errorf("not a replication controller: %#v", obj)
|
||||||
@@ -123,8 +124,8 @@ func (rs *RegistryStorage) Update(obj interface{}) (<-chan interface{}, error) {
|
|||||||
if errs := validation.ValidateReplicationController(controller); len(errs) > 0 {
|
if errs := validation.ValidateReplicationController(controller); len(errs) > 0 {
|
||||||
return nil, errors.NewInvalid("replicationController", controller.ID, errs)
|
return nil, errors.NewInvalid("replicationController", controller.ID, errs)
|
||||||
}
|
}
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
err := rs.registry.UpdateController(*controller)
|
err := rs.registry.UpdateController(controller)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -148,7 +149,7 @@ func (rs *RegistryStorage) Watch(label, field labels.Selector, resourceVersion u
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) waitForController(ctrl api.ReplicationController) (interface{}, error) {
|
func (rs *RegistryStorage) waitForController(ctrl *api.ReplicationController) (runtime.Object, error) {
|
||||||
for {
|
for {
|
||||||
pods, err := rs.podRegistry.ListPods(labels.Set(ctrl.DesiredState.ReplicaSelector).AsSelector())
|
pods, err := rs.podRegistry.ListPods(labels.Set(ctrl.DesiredState.ReplicaSelector).AsSelector())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -112,13 +112,13 @@ func TestControllerDecode(t *testing.T) {
|
|||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
body, err := runtime.Encode(controller)
|
body, err := runtime.DefaultCodec.Encode(controller)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
controllerOut := storage.New()
|
controllerOut := storage.New()
|
||||||
if err := runtime.DecodeInto(body, controllerOut); err != nil {
|
if err := runtime.DefaultCodec.DecodeInto(body, controllerOut); err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ type Registry interface {
|
|||||||
ListEndpoints() (*api.EndpointsList, error)
|
ListEndpoints() (*api.EndpointsList, error)
|
||||||
GetEndpoints(name string) (*api.Endpoints, error)
|
GetEndpoints(name string) (*api.Endpoints, error)
|
||||||
WatchEndpoints(labels, fields labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchEndpoints(labels, fields labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
UpdateEndpoints(e api.Endpoints) error
|
UpdateEndpoints(e *api.Endpoints) error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,12 +39,12 @@ func NewStorage(registry Registry) apiserver.RESTStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get satisfies the RESTStorage interface.
|
// Get satisfies the RESTStorage interface.
|
||||||
func (rs *Storage) Get(id string) (interface{}, error) {
|
func (rs *Storage) Get(id string) (runtime.Object, error) {
|
||||||
return rs.registry.GetEndpoints(id)
|
return rs.registry.GetEndpoints(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// List satisfies the RESTStorage interface.
|
// List satisfies the RESTStorage interface.
|
||||||
func (rs *Storage) List(selector labels.Selector) (interface{}, error) {
|
func (rs *Storage) List(selector labels.Selector) (runtime.Object, error) {
|
||||||
if !selector.Empty() {
|
if !selector.Empty() {
|
||||||
return nil, errors.New("label selectors are not supported on endpoints")
|
return nil, errors.New("label selectors are not supported on endpoints")
|
||||||
}
|
}
|
||||||
@@ -57,21 +58,21 @@ func (rs *Storage) Watch(label, field labels.Selector, resourceVersion uint64) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create satisfies the RESTStorage interface but is unimplemented.
|
// Create satisfies the RESTStorage interface but is unimplemented.
|
||||||
func (rs *Storage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (rs *Storage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
return nil, errors.New("unimplemented")
|
return nil, errors.New("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update satisfies the RESTStorage interface but is unimplemented.
|
// Update satisfies the RESTStorage interface but is unimplemented.
|
||||||
func (rs *Storage) Update(obj interface{}) (<-chan interface{}, error) {
|
func (rs *Storage) Update(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
return nil, errors.New("unimplemented")
|
return nil, errors.New("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete satisfies the RESTStorage interface but is unimplemented.
|
// Delete satisfies the RESTStorage interface but is unimplemented.
|
||||||
func (rs *Storage) Delete(id string) (<-chan interface{}, error) {
|
func (rs *Storage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
return nil, errors.New("unimplemented")
|
return nil, errors.New("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// New implements the RESTStorage interface.
|
// New implements the RESTStorage interface.
|
||||||
func (rs Storage) New() interface{} {
|
func (rs Storage) New() runtime.Object {
|
||||||
return &api.Endpoints{}
|
return &api.Endpoints{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ func NewRegistry(client tools.EtcdClient) *Registry {
|
|||||||
registry := &Registry{
|
registry := &Registry{
|
||||||
EtcdHelper: tools.EtcdHelper{
|
EtcdHelper: tools.EtcdHelper{
|
||||||
client,
|
client,
|
||||||
runtime.Codec,
|
runtime.DefaultCodec,
|
||||||
runtime.ResourceVersioner,
|
runtime.DefaultResourceVersioner,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
registry.manifestFactory = &BasicManifestFactory{
|
registry.manifestFactory = &BasicManifestFactory{
|
||||||
@@ -82,7 +82,7 @@ func (r *Registry) ListPods(selector labels.Selector) (*api.PodList, error) {
|
|||||||
|
|
||||||
// WatchPods begins watching for new, changed, or deleted pods.
|
// WatchPods begins watching for new, changed, or deleted pods.
|
||||||
func (r *Registry) WatchPods(resourceVersion uint64, filter func(*api.Pod) bool) (watch.Interface, error) {
|
func (r *Registry) WatchPods(resourceVersion uint64, filter func(*api.Pod) bool) (watch.Interface, error) {
|
||||||
return r.WatchList("/registry/pods", resourceVersion, func(obj interface{}) bool {
|
return r.WatchList("/registry/pods", resourceVersion, func(obj runtime.Object) bool {
|
||||||
pod, ok := obj.(*api.Pod)
|
pod, ok := obj.(*api.Pod)
|
||||||
if !ok {
|
if !ok {
|
||||||
glog.Errorf("Unexpected object during pod watch: %#v", obj)
|
glog.Errorf("Unexpected object during pod watch: %#v", obj)
|
||||||
@@ -110,14 +110,14 @@ func makeContainerKey(machine string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreatePod creates a pod based on a specification.
|
// CreatePod creates a pod based on a specification.
|
||||||
func (r *Registry) CreatePod(pod api.Pod) error {
|
func (r *Registry) CreatePod(pod *api.Pod) error {
|
||||||
// Set current status to "Waiting".
|
// Set current status to "Waiting".
|
||||||
pod.CurrentState.Status = api.PodWaiting
|
pod.CurrentState.Status = api.PodWaiting
|
||||||
pod.CurrentState.Host = ""
|
pod.CurrentState.Host = ""
|
||||||
// DesiredState.Host == "" is a signal to the scheduler that this pod needs scheduling.
|
// DesiredState.Host == "" is a signal to the scheduler that this pod needs scheduling.
|
||||||
pod.DesiredState.Status = api.PodRunning
|
pod.DesiredState.Status = api.PodRunning
|
||||||
pod.DesiredState.Host = ""
|
pod.DesiredState.Host = ""
|
||||||
return r.CreateObj(makePodKey(pod.ID), &pod)
|
return r.CreateObj(makePodKey(pod.ID), pod)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyBinding implements binding's registry
|
// ApplyBinding implements binding's registry
|
||||||
@@ -129,7 +129,7 @@ func (r *Registry) ApplyBinding(binding *api.Binding) error {
|
|||||||
// Returns the current state of the pod, or an error.
|
// Returns the current state of the pod, or an error.
|
||||||
func (r *Registry) setPodHostTo(podID, oldMachine, machine string) (finalPod *api.Pod, err error) {
|
func (r *Registry) setPodHostTo(podID, oldMachine, machine string) (finalPod *api.Pod, err error) {
|
||||||
podKey := makePodKey(podID)
|
podKey := makePodKey(podID)
|
||||||
err = r.AtomicUpdate(podKey, &api.Pod{}, func(obj interface{}) (interface{}, error) {
|
err = r.AtomicUpdate(podKey, &api.Pod{}, func(obj runtime.Object) (runtime.Object, error) {
|
||||||
pod, ok := obj.(*api.Pod)
|
pod, ok := obj.(*api.Pod)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected object: %#v", obj)
|
return nil, fmt.Errorf("unexpected object: %#v", obj)
|
||||||
@@ -156,13 +156,13 @@ func (r *Registry) assignPod(podID string, machine string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
contKey := makeContainerKey(machine)
|
contKey := makeContainerKey(machine)
|
||||||
err = r.AtomicUpdate(contKey, &api.ContainerManifestList{}, func(in interface{}) (interface{}, error) {
|
err = r.AtomicUpdate(contKey, &api.ContainerManifestList{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
manifests := *in.(*api.ContainerManifestList)
|
manifests := *in.(*api.ContainerManifestList)
|
||||||
manifests.Items = append(manifests.Items, manifest)
|
manifests.Items = append(manifests.Items, manifest)
|
||||||
if !constraint.Allowed(manifests.Items) {
|
if !constraint.Allowed(manifests.Items) {
|
||||||
return nil, fmt.Errorf("The assignment would cause a constraint violation")
|
return nil, fmt.Errorf("The assignment would cause a constraint violation")
|
||||||
}
|
}
|
||||||
return manifests, nil
|
return &manifests, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Put the pod's host back the way it was. This is a terrible hack that
|
// Put the pod's host back the way it was. This is a terrible hack that
|
||||||
@@ -174,7 +174,7 @@ func (r *Registry) assignPod(podID string, machine string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Registry) UpdatePod(pod api.Pod) error {
|
func (r *Registry) UpdatePod(pod *api.Pod) error {
|
||||||
return fmt.Errorf("unimplemented!")
|
return fmt.Errorf("unimplemented!")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ func (r *Registry) DeletePod(podID string) error {
|
|||||||
}
|
}
|
||||||
// Next, remove the pod from the machine atomically.
|
// Next, remove the pod from the machine atomically.
|
||||||
contKey := makeContainerKey(machine)
|
contKey := makeContainerKey(machine)
|
||||||
return r.AtomicUpdate(contKey, &api.ContainerManifestList{}, func(in interface{}) (interface{}, error) {
|
return r.AtomicUpdate(contKey, &api.ContainerManifestList{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
manifests := in.(*api.ContainerManifestList)
|
manifests := in.(*api.ContainerManifestList)
|
||||||
newManifests := make([]api.ContainerManifest, 0, len(manifests.Items))
|
newManifests := make([]api.ContainerManifest, 0, len(manifests.Items))
|
||||||
found := false
|
found := false
|
||||||
@@ -258,7 +258,7 @@ func (r *Registry) GetController(controllerID string) (*api.ReplicationControlle
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateController creates a new ReplicationController.
|
// CreateController creates a new ReplicationController.
|
||||||
func (r *Registry) CreateController(controller api.ReplicationController) error {
|
func (r *Registry) CreateController(controller *api.ReplicationController) error {
|
||||||
err := r.CreateObj(makeControllerKey(controller.ID), controller)
|
err := r.CreateObj(makeControllerKey(controller.ID), controller)
|
||||||
if tools.IsEtcdNodeExist(err) {
|
if tools.IsEtcdNodeExist(err) {
|
||||||
return errors.NewAlreadyExists("replicationController", controller.ID)
|
return errors.NewAlreadyExists("replicationController", controller.ID)
|
||||||
@@ -267,8 +267,8 @@ func (r *Registry) CreateController(controller api.ReplicationController) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateController replaces an existing ReplicationController.
|
// UpdateController replaces an existing ReplicationController.
|
||||||
func (r *Registry) UpdateController(controller api.ReplicationController) error {
|
func (r *Registry) UpdateController(controller *api.ReplicationController) error {
|
||||||
return r.SetObj(makeControllerKey(controller.ID), &controller)
|
return r.SetObj(makeControllerKey(controller.ID), controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteController deletes a ReplicationController specified by its ID.
|
// DeleteController deletes a ReplicationController specified by its ID.
|
||||||
@@ -293,7 +293,7 @@ func (r *Registry) ListServices() (*api.ServiceList, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateService creates a new Service.
|
// CreateService creates a new Service.
|
||||||
func (r *Registry) CreateService(svc api.Service) error {
|
func (r *Registry) CreateService(svc *api.Service) error {
|
||||||
err := r.CreateObj(makeServiceKey(svc.ID), svc)
|
err := r.CreateObj(makeServiceKey(svc.ID), svc)
|
||||||
if tools.IsEtcdNodeExist(err) {
|
if tools.IsEtcdNodeExist(err) {
|
||||||
return errors.NewAlreadyExists("service", svc.ID)
|
return errors.NewAlreadyExists("service", svc.ID)
|
||||||
@@ -352,8 +352,8 @@ func (r *Registry) DeleteService(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateService replaces an existing Service.
|
// UpdateService replaces an existing Service.
|
||||||
func (r *Registry) UpdateService(svc api.Service) error {
|
func (r *Registry) UpdateService(svc *api.Service) error {
|
||||||
return r.SetObj(makeServiceKey(svc.ID), &svc)
|
return r.SetObj(makeServiceKey(svc.ID), svc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WatchServices begins watching for new, changed, or deleted service configurations.
|
// WatchServices begins watching for new, changed, or deleted service configurations.
|
||||||
@@ -378,10 +378,10 @@ func (r *Registry) ListEndpoints() (*api.EndpointsList, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateEndpoints update Endpoints of a Service.
|
// UpdateEndpoints update Endpoints of a Service.
|
||||||
func (r *Registry) UpdateEndpoints(e api.Endpoints) error {
|
func (r *Registry) UpdateEndpoints(e *api.Endpoints) error {
|
||||||
// TODO: this is a really bad misuse of AtomicUpdate, need to compute a diff inside the loop.
|
// TODO: this is a really bad misuse of AtomicUpdate, need to compute a diff inside the loop.
|
||||||
return r.AtomicUpdate(makeServiceEndpointsKey(e.ID), &api.Endpoints{},
|
return r.AtomicUpdate(makeServiceEndpointsKey(e.ID), &api.Endpoints{},
|
||||||
func(input interface{}) (interface{}, error) {
|
func(input runtime.Object) (runtime.Object, error) {
|
||||||
// TODO: racy - label query is returning different results for two simultaneous updaters
|
// TODO: racy - label query is returning different results for two simultaneous updaters
|
||||||
return e, nil
|
return e, nil
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func NewTestEtcdRegistry(client tools.EtcdClient) *Registry {
|
|||||||
|
|
||||||
func TestEtcdGetPod(t *testing.T) {
|
func TestEtcdGetPod(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.Set("/registry/pods/foo", runtime.EncodeOrDie(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
fakeClient.Set("/registry/pods/foo", runtime.DefaultScheme.EncodeOrDie(&api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
pod, err := registry.GetPod("foo")
|
pod, err := registry.GetPod("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -77,9 +77,9 @@ func TestEtcdCreatePod(t *testing.T) {
|
|||||||
},
|
},
|
||||||
E: tools.EtcdErrorNotFound,
|
E: tools.EtcdErrorNotFound,
|
||||||
}
|
}
|
||||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(&api.ContainerManifestList{}), 0)
|
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.DefaultScheme.EncodeOrDie(&api.ContainerManifestList{}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreatePod(api.Pod{
|
err := registry.CreatePod(&api.Pod{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -108,7 +108,7 @@ func TestEtcdCreatePod(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var pod api.Pod
|
var pod api.Pod
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &pod)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ func TestEtcdCreatePod(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &manifests)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &manifests)
|
||||||
if len(manifests.Items) != 1 || manifests.Items[0].ID != "foo" {
|
if len(manifests.Items) != 1 || manifests.Items[0].ID != "foo" {
|
||||||
t.Errorf("Unexpected manifest list: %#v", manifests)
|
t.Errorf("Unexpected manifest list: %#v", manifests)
|
||||||
}
|
}
|
||||||
@@ -133,13 +133,13 @@ func TestEtcdCreatePodAlreadyExisting(t *testing.T) {
|
|||||||
fakeClient.Data["/registry/pods/foo"] = tools.EtcdResponseWithError{
|
fakeClient.Data["/registry/pods/foo"] = tools.EtcdResponseWithError{
|
||||||
R: &etcd.Response{
|
R: &etcd.Response{
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: runtime.EncodeOrDie(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Pod{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
E: nil,
|
E: nil,
|
||||||
}
|
}
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreatePod(api.Pod{
|
err := registry.CreatePod(&api.Pod{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -165,7 +165,7 @@ func TestEtcdCreatePodWithContainersError(t *testing.T) {
|
|||||||
E: tools.EtcdErrorValueRequired,
|
E: tools.EtcdErrorValueRequired,
|
||||||
}
|
}
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreatePod(api.Pod{
|
err := registry.CreatePod(&api.Pod{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -205,7 +205,7 @@ func TestEtcdCreatePodWithContainersNotFound(t *testing.T) {
|
|||||||
E: tools.EtcdErrorNotFound,
|
E: tools.EtcdErrorNotFound,
|
||||||
}
|
}
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreatePod(api.Pod{
|
err := registry.CreatePod(&api.Pod{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -235,7 +235,7 @@ func TestEtcdCreatePodWithContainersNotFound(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var pod api.Pod
|
var pod api.Pod
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &pod)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ func TestEtcdCreatePodWithContainersNotFound(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &manifests)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &manifests)
|
||||||
if len(manifests.Items) != 1 || manifests.Items[0].ID != "foo" {
|
if len(manifests.Items) != 1 || manifests.Items[0].ID != "foo" {
|
||||||
t.Errorf("Unexpected manifest list: %#v", manifests)
|
t.Errorf("Unexpected manifest list: %#v", manifests)
|
||||||
}
|
}
|
||||||
@@ -264,13 +264,13 @@ func TestEtcdCreatePodWithExistingContainers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
E: tools.EtcdErrorNotFound,
|
E: tools.EtcdErrorNotFound,
|
||||||
}
|
}
|
||||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(api.ContainerManifestList{
|
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.DefaultScheme.EncodeOrDie(&api.ContainerManifestList{
|
||||||
Items: []api.ContainerManifest{
|
Items: []api.ContainerManifest{
|
||||||
{ID: "bar"},
|
{ID: "bar"},
|
||||||
},
|
},
|
||||||
}), 0)
|
}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreatePod(api.Pod{
|
err := registry.CreatePod(&api.Pod{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -300,7 +300,7 @@ func TestEtcdCreatePodWithExistingContainers(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var pod api.Pod
|
var pod api.Pod
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &pod)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ func TestEtcdCreatePodWithExistingContainers(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &manifests)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &manifests)
|
||||||
if len(manifests.Items) != 2 || manifests.Items[1].ID != "foo" {
|
if len(manifests.Items) != 2 || manifests.Items[1].ID != "foo" {
|
||||||
t.Errorf("Unexpected manifest list: %#v", manifests)
|
t.Errorf("Unexpected manifest list: %#v", manifests)
|
||||||
}
|
}
|
||||||
@@ -325,11 +325,11 @@ func TestEtcdDeletePod(t *testing.T) {
|
|||||||
fakeClient.TestIndex = true
|
fakeClient.TestIndex = true
|
||||||
|
|
||||||
key := "/registry/pods/foo"
|
key := "/registry/pods/foo"
|
||||||
fakeClient.Set(key, runtime.EncodeOrDie(api.Pod{
|
fakeClient.Set(key, runtime.DefaultScheme.EncodeOrDie(&api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
DesiredState: api.PodState{Host: "machine"},
|
DesiredState: api.PodState{Host: "machine"},
|
||||||
}), 0)
|
}), 0)
|
||||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(&api.ContainerManifestList{
|
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.DefaultScheme.EncodeOrDie(&api.ContainerManifestList{
|
||||||
Items: []api.ContainerManifest{
|
Items: []api.ContainerManifest{
|
||||||
{ID: "foo"},
|
{ID: "foo"},
|
||||||
},
|
},
|
||||||
@@ -350,7 +350,7 @@ func TestEtcdDeletePod(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var manifests api.ContainerManifestList
|
var manifests api.ContainerManifestList
|
||||||
runtime.DecodeInto([]byte(response.Node.Value), &manifests)
|
runtime.DefaultCodec.DecodeInto([]byte(response.Node.Value), &manifests)
|
||||||
if len(manifests.Items) != 0 {
|
if len(manifests.Items) != 0 {
|
||||||
t.Errorf("Unexpected container set: %s, expected empty", response.Node.Value)
|
t.Errorf("Unexpected container set: %s, expected empty", response.Node.Value)
|
||||||
}
|
}
|
||||||
@@ -361,11 +361,11 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) {
|
|||||||
fakeClient.TestIndex = true
|
fakeClient.TestIndex = true
|
||||||
|
|
||||||
key := "/registry/pods/foo"
|
key := "/registry/pods/foo"
|
||||||
fakeClient.Set(key, runtime.EncodeOrDie(api.Pod{
|
fakeClient.Set(key, runtime.DefaultScheme.EncodeOrDie(&api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
DesiredState: api.PodState{Host: "machine"},
|
DesiredState: api.PodState{Host: "machine"},
|
||||||
}), 0)
|
}), 0)
|
||||||
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(&api.ContainerManifestList{
|
fakeClient.Set("/registry/hosts/machine/kubelet", runtime.DefaultScheme.EncodeOrDie(&api.ContainerManifestList{
|
||||||
Items: []api.ContainerManifest{
|
Items: []api.ContainerManifest{
|
||||||
{ID: "foo"},
|
{ID: "foo"},
|
||||||
{ID: "bar"},
|
{ID: "bar"},
|
||||||
@@ -388,7 +388,7 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var manifests api.ContainerManifestList
|
var manifests api.ContainerManifestList
|
||||||
runtime.DecodeInto([]byte(response.Node.Value), &manifests)
|
runtime.DefaultCodec.DecodeInto([]byte(response.Node.Value), &manifests)
|
||||||
if len(manifests.Items) != 1 {
|
if len(manifests.Items) != 1 {
|
||||||
t.Fatalf("Unexpected manifest set: %#v, expected empty", manifests)
|
t.Fatalf("Unexpected manifest set: %#v, expected empty", manifests)
|
||||||
}
|
}
|
||||||
@@ -445,13 +445,13 @@ func TestEtcdListPods(t *testing.T) {
|
|||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Nodes: []*etcd.Node{
|
Nodes: []*etcd.Node{
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.Pod{
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
DesiredState: api.PodState{Host: "machine"},
|
DesiredState: api.PodState{Host: "machine"},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.Pod{
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Pod{
|
||||||
JSONBase: api.JSONBase{ID: "bar"},
|
JSONBase: api.JSONBase{ID: "bar"},
|
||||||
DesiredState: api.PodState{Host: "machine"},
|
DesiredState: api.PodState{Host: "machine"},
|
||||||
}),
|
}),
|
||||||
@@ -520,10 +520,10 @@ func TestEtcdListControllers(t *testing.T) {
|
|||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Nodes: []*etcd.Node{
|
Nodes: []*etcd.Node{
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.ReplicationController{JSONBase: api.JSONBase{ID: "bar"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -543,7 +543,7 @@ func TestEtcdListControllers(t *testing.T) {
|
|||||||
|
|
||||||
func TestEtcdGetController(t *testing.T) {
|
func TestEtcdGetController(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.Set("/registry/controllers/foo", runtime.EncodeOrDie(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
fakeClient.Set("/registry/controllers/foo", runtime.DefaultScheme.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
ctrl, err := registry.GetController("foo")
|
ctrl, err := registry.GetController("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -593,7 +593,7 @@ func TestEtcdDeleteController(t *testing.T) {
|
|||||||
func TestEtcdCreateController(t *testing.T) {
|
func TestEtcdCreateController(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreateController(api.ReplicationController{
|
err := registry.CreateController(&api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -607,7 +607,7 @@ func TestEtcdCreateController(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var ctrl api.ReplicationController
|
var ctrl api.ReplicationController
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &ctrl)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &ctrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -619,10 +619,10 @@ func TestEtcdCreateController(t *testing.T) {
|
|||||||
|
|
||||||
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
|
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.Set("/registry/controllers/foo", runtime.EncodeOrDie(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
fakeClient.Set("/registry/controllers/foo", runtime.DefaultScheme.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
|
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreateController(api.ReplicationController{
|
err := registry.CreateController(&api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{
|
JSONBase: api.JSONBase{
|
||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
@@ -636,9 +636,9 @@ func TestEtcdUpdateController(t *testing.T) {
|
|||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.TestIndex = true
|
fakeClient.TestIndex = true
|
||||||
|
|
||||||
resp, _ := fakeClient.Set("/registry/controllers/foo", runtime.EncodeOrDie(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
resp, _ := fakeClient.Set("/registry/controllers/foo", runtime.DefaultScheme.EncodeOrDie(&api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.UpdateController(api.ReplicationController{
|
err := registry.UpdateController(&api.ReplicationController{
|
||||||
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex},
|
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex},
|
||||||
DesiredState: api.ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
Replicas: 2,
|
Replicas: 2,
|
||||||
@@ -662,10 +662,10 @@ func TestEtcdListServices(t *testing.T) {
|
|||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Nodes: []*etcd.Node{
|
Nodes: []*etcd.Node{
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "foo"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "bar"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -686,7 +686,7 @@ func TestEtcdListServices(t *testing.T) {
|
|||||||
func TestEtcdCreateService(t *testing.T) {
|
func TestEtcdCreateService(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreateService(api.Service{
|
err := registry.CreateService(&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -699,7 +699,7 @@ func TestEtcdCreateService(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var service api.Service
|
var service api.Service
|
||||||
err = runtime.DecodeInto([]byte(resp.Node.Value), &service)
|
err = runtime.DefaultCodec.DecodeInto([]byte(resp.Node.Value), &service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -711,9 +711,9 @@ func TestEtcdCreateService(t *testing.T) {
|
|||||||
|
|
||||||
func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
|
func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.Set("/registry/services/specs/foo", runtime.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
fakeClient.Set("/registry/services/specs/foo", runtime.DefaultScheme.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
err := registry.CreateService(api.Service{
|
err := registry.CreateService(&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
})
|
})
|
||||||
if !errors.IsAlreadyExists(err) {
|
if !errors.IsAlreadyExists(err) {
|
||||||
@@ -723,7 +723,7 @@ func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
|
|||||||
|
|
||||||
func TestEtcdGetService(t *testing.T) {
|
func TestEtcdGetService(t *testing.T) {
|
||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.Set("/registry/services/specs/foo", runtime.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
fakeClient.Set("/registry/services/specs/foo", runtime.DefaultScheme.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
service, err := registry.GetService("foo")
|
service, err := registry.GetService("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -775,7 +775,7 @@ func TestEtcdUpdateService(t *testing.T) {
|
|||||||
fakeClient := tools.NewFakeEtcdClient(t)
|
fakeClient := tools.NewFakeEtcdClient(t)
|
||||||
fakeClient.TestIndex = true
|
fakeClient.TestIndex = true
|
||||||
|
|
||||||
resp, _ := fakeClient.Set("/registry/services/specs/foo", runtime.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
resp, _ := fakeClient.Set("/registry/services/specs/foo", runtime.DefaultScheme.EncodeOrDie(&api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
registry := NewTestEtcdRegistry(fakeClient)
|
registry := NewTestEtcdRegistry(fakeClient)
|
||||||
testService := api.Service{
|
testService := api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex},
|
JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex},
|
||||||
@@ -786,7 +786,7 @@ func TestEtcdUpdateService(t *testing.T) {
|
|||||||
"baz": "bar",
|
"baz": "bar",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := registry.UpdateService(testService)
|
err := registry.UpdateService(&testService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -812,10 +812,10 @@ func TestEtcdListEndpoints(t *testing.T) {
|
|||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Nodes: []*etcd.Node{
|
Nodes: []*etcd.Node{
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:8345"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:8345"}}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: runtime.EncodeOrDie(api.Endpoints{JSONBase: api.JSONBase{ID: "bar"}}),
|
Value: runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "bar"}}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -841,7 +841,7 @@ func TestEtcdGetEndpoints(t *testing.T) {
|
|||||||
Endpoints: []string{"127.0.0.1:34855"},
|
Endpoints: []string{"127.0.0.1:34855"},
|
||||||
}
|
}
|
||||||
|
|
||||||
fakeClient.Set("/registry/services/endpoints/foo", runtime.EncodeOrDie(endpoints), 0)
|
fakeClient.Set("/registry/services/endpoints/foo", runtime.DefaultScheme.EncodeOrDie(endpoints), 0)
|
||||||
|
|
||||||
got, err := registry.GetEndpoints("foo")
|
got, err := registry.GetEndpoints("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -862,9 +862,9 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
|
|||||||
Endpoints: []string{"baz", "bar"},
|
Endpoints: []string{"baz", "bar"},
|
||||||
}
|
}
|
||||||
|
|
||||||
fakeClient.Set("/registry/services/endpoints/foo", runtime.EncodeOrDie(api.Endpoints{}), 0)
|
fakeClient.Set("/registry/services/endpoints/foo", runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{}), 0)
|
||||||
|
|
||||||
err := registry.UpdateEndpoints(endpoints)
|
err := registry.UpdateEndpoints(&endpoints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -874,7 +874,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error %v", err)
|
t.Fatalf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
var endpointsOut api.Endpoints
|
var endpointsOut api.Endpoints
|
||||||
err = runtime.DecodeInto([]byte(response.Node.Value), &endpointsOut)
|
err = runtime.DefaultCodec.DecodeInto([]byte(response.Node.Value), &endpointsOut)
|
||||||
if !reflect.DeepEqual(endpoints, endpointsOut) {
|
if !reflect.DeepEqual(endpoints, endpointsOut) {
|
||||||
t.Errorf("Unexpected endpoints: %#v, expected %#v", endpointsOut, endpoints)
|
t.Errorf("Unexpected endpoints: %#v, expected %#v", endpointsOut, endpoints)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ func NewRegistryStorage(m Registry) apiserver.RESTStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
minion, ok := obj.(*api.Minion)
|
minion, ok := obj.(*api.Minion)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("not a minion: %#v", obj)
|
return nil, fmt.Errorf("not a minion: %#v", obj)
|
||||||
@@ -48,7 +49,7 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
|
|
||||||
minion.CreationTimestamp = util.Now()
|
minion.CreationTimestamp = util.Now()
|
||||||
|
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
err := rs.registry.Insert(minion.ID)
|
err := rs.registry.Insert(minion.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -64,7 +65,7 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Delete(id string) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
exists, err := rs.registry.Contains(id)
|
exists, err := rs.registry.Contains(id)
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, ErrDoesNotExist
|
return nil, ErrDoesNotExist
|
||||||
@@ -72,12 +73,12 @@ func (rs *RegistryStorage) Delete(id string) (<-chan interface{}, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
return &api.Status{Status: api.StatusSuccess}, rs.registry.Delete(id)
|
return &api.Status{Status: api.StatusSuccess}, rs.registry.Delete(id)
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
func (rs *RegistryStorage) Get(id string) (runtime.Object, error) {
|
||||||
exists, err := rs.registry.Contains(id)
|
exists, err := rs.registry.Contains(id)
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, ErrDoesNotExist
|
return nil, ErrDoesNotExist
|
||||||
@@ -85,26 +86,26 @@ func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
|||||||
return rs.toApiMinion(id), err
|
return rs.toApiMinion(id), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) List(selector labels.Selector) (interface{}, error) {
|
func (rs *RegistryStorage) List(selector labels.Selector) (runtime.Object, error) {
|
||||||
nameList, err := rs.registry.List()
|
nameList, err := rs.registry.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var list api.MinionList
|
var list api.MinionList
|
||||||
for _, name := range nameList {
|
for _, name := range nameList {
|
||||||
list.Items = append(list.Items, rs.toApiMinion(name))
|
list.Items = append(list.Items, *rs.toApiMinion(name))
|
||||||
}
|
}
|
||||||
return list, nil
|
return &list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs RegistryStorage) New() interface{} {
|
func (rs RegistryStorage) New() runtime.Object {
|
||||||
return &api.Minion{}
|
return &api.Minion{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Update(minion interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Update(minion runtime.Object) (<-chan runtime.Object, error) {
|
||||||
return nil, fmt.Errorf("Minions can only be created (inserted) and deleted.")
|
return nil, fmt.Errorf("Minions can only be created (inserted) and deleted.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) toApiMinion(name string) api.Minion {
|
func (rs *RegistryStorage) toApiMinion(name string) *api.Minion {
|
||||||
return api.Minion{JSONBase: api.JSONBase{ID: name}}
|
return &api.Minion{JSONBase: api.JSONBase{ID: name}}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ func TestMinionRegistryStorage(t *testing.T) {
|
|||||||
m := NewRegistry([]string{"foo", "bar"})
|
m := NewRegistry([]string{"foo", "bar"})
|
||||||
ms := NewRegistryStorage(m)
|
ms := NewRegistryStorage(m)
|
||||||
|
|
||||||
if obj, err := ms.Get("foo"); err != nil || obj.(api.Minion).ID != "foo" {
|
if obj, err := ms.Get("foo"); err != nil || obj.(*api.Minion).ID != "foo" {
|
||||||
t.Errorf("missing expected object")
|
t.Errorf("missing expected object")
|
||||||
}
|
}
|
||||||
if obj, err := ms.Get("bar"); err != nil || obj.(api.Minion).ID != "bar" {
|
if obj, err := ms.Get("bar"); err != nil || obj.(*api.Minion).ID != "bar" {
|
||||||
t.Errorf("missing expected object")
|
t.Errorf("missing expected object")
|
||||||
}
|
}
|
||||||
if _, err := ms.Get("baz"); err != ErrDoesNotExist {
|
if _, err := ms.Get("baz"); err != ErrDoesNotExist {
|
||||||
@@ -43,10 +43,10 @@ func TestMinionRegistryStorage(t *testing.T) {
|
|||||||
t.Errorf("insert failed")
|
t.Errorf("insert failed")
|
||||||
}
|
}
|
||||||
obj := <-c
|
obj := <-c
|
||||||
if m, ok := obj.(api.Minion); !ok || m.ID != "baz" {
|
if m, ok := obj.(*api.Minion); !ok || m.ID != "baz" {
|
||||||
t.Errorf("insert return value was weird: %#v", obj)
|
t.Errorf("insert return value was weird: %#v", obj)
|
||||||
}
|
}
|
||||||
if obj, err := ms.Get("baz"); err != nil || obj.(api.Minion).ID != "baz" {
|
if obj, err := ms.Get("baz"); err != nil || obj.(*api.Minion).ID != "baz" {
|
||||||
t.Errorf("insert didn't actually insert")
|
t.Errorf("insert didn't actually insert")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ func TestMinionRegistryStorage(t *testing.T) {
|
|||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(list.(api.MinionList).Items, expect) {
|
if !reflect.DeepEqual(list.(*api.MinionList).Items, expect) {
|
||||||
t.Errorf("Unexpected list value: %#v", list)
|
t.Errorf("Unexpected list value: %#v", list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ type Registry interface {
|
|||||||
// Get a specific pod
|
// Get a specific pod
|
||||||
GetPod(podID string) (*api.Pod, error)
|
GetPod(podID string) (*api.Pod, error)
|
||||||
// Create a pod based on a specification.
|
// Create a pod based on a specification.
|
||||||
CreatePod(pod api.Pod) error
|
CreatePod(pod *api.Pod) error
|
||||||
// Update an existing pod
|
// Update an existing pod
|
||||||
UpdatePod(pod api.Pod) error
|
UpdatePod(pod *api.Pod) error
|
||||||
// Delete an existing pod
|
// Delete an existing pod
|
||||||
DeletePod(podID string) error
|
DeletePod(podID string) error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ func NewRegistryStorage(config *RegistryStorageConfig) apiserver.RESTStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
pod := obj.(*api.Pod)
|
pod := obj.(*api.Pod)
|
||||||
if len(pod.ID) == 0 {
|
if len(pod.ID) == 0 {
|
||||||
pod.ID = uuid.NewUUID().String()
|
pod.ID = uuid.NewUUID().String()
|
||||||
@@ -76,21 +77,21 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
|
|
||||||
pod.CreationTimestamp = util.Now()
|
pod.CreationTimestamp = util.Now()
|
||||||
|
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
if err := rs.registry.CreatePod(*pod); err != nil {
|
if err := rs.registry.CreatePod(pod); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return rs.registry.GetPod(pod.ID)
|
return rs.registry.GetPod(pod.ID)
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Delete(id string) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeletePod(id)
|
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeletePod(id)
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
func (rs *RegistryStorage) Get(id string) (runtime.Object, error) {
|
||||||
pod, err := rs.registry.GetPod(id)
|
pod, err := rs.registry.GetPod(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pod, err
|
return pod, err
|
||||||
@@ -106,7 +107,7 @@ func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
|||||||
return pod, err
|
return pod, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) List(selector labels.Selector) (interface{}, error) {
|
func (rs *RegistryStorage) List(selector labels.Selector) (runtime.Object, error) {
|
||||||
pods, err := rs.registry.ListPods(selector)
|
pods, err := rs.registry.ListPods(selector)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for i := range pods.Items {
|
for i := range pods.Items {
|
||||||
@@ -131,17 +132,17 @@ func (rs *RegistryStorage) Watch(label, field labels.Selector, resourceVersion u
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs RegistryStorage) New() interface{} {
|
func (rs RegistryStorage) New() runtime.Object {
|
||||||
return &api.Pod{}
|
return &api.Pod{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Update(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Update(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
pod := obj.(*api.Pod)
|
pod := obj.(*api.Pod)
|
||||||
if errs := validation.ValidatePod(pod); len(errs) > 0 {
|
if errs := validation.ValidatePod(pod); len(errs) > 0 {
|
||||||
return nil, errors.NewInvalid("pod", pod.ID, errs)
|
return nil, errors.NewInvalid("pod", pod.ID, errs)
|
||||||
}
|
}
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
if err := rs.registry.UpdatePod(*pod); err != nil {
|
if err := rs.registry.UpdatePod(pod); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return rs.registry.GetPod(pod.ID)
|
return rs.registry.GetPod(pod.ID)
|
||||||
@@ -235,7 +236,7 @@ func getPodStatus(pod *api.Pod) api.PodStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) waitForPodRunning(pod api.Pod) (interface{}, error) {
|
func (rs *RegistryStorage) waitForPodRunning(pod *api.Pod) (runtime.Object, error) {
|
||||||
for {
|
for {
|
||||||
podObj, err := rs.Get(pod.ID)
|
podObj, err := rs.Get(pod.ID)
|
||||||
if err != nil || podObj == nil {
|
if err != nil || podObj == nil {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
"github.com/fsouza/go-dockerclient"
|
"github.com/fsouza/go-dockerclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func expectApiStatusError(t *testing.T, ch <-chan interface{}, msg string) {
|
func expectApiStatusError(t *testing.T, ch <-chan runtime.Object, msg string) {
|
||||||
out := <-ch
|
out := <-ch
|
||||||
status, ok := out.(*api.Status)
|
status, ok := out.(*api.Status)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -44,7 +44,7 @@ func expectApiStatusError(t *testing.T, ch <-chan interface{}, msg string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectPod(t *testing.T, ch <-chan interface{}) (*api.Pod, bool) {
|
func expectPod(t *testing.T, ch <-chan runtime.Object) (*api.Pod, bool) {
|
||||||
out := <-ch
|
out := <-ch
|
||||||
pod, ok := out.(*api.Pod)
|
pod, ok := out.(*api.Pod)
|
||||||
if !ok || pod == nil {
|
if !ok || pod == nil {
|
||||||
@@ -178,13 +178,13 @@ func TestPodDecode(t *testing.T) {
|
|||||||
ID: "foo",
|
ID: "foo",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
body, err := runtime.Encode(expected)
|
body, err := runtime.DefaultCodec.Encode(expected)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual := storage.New()
|
actual := storage.New()
|
||||||
if err := runtime.DecodeInto(body, actual); err != nil {
|
if err := runtime.DefaultCodec.DecodeInto(body, actual); err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ func (r *ControllerRegistry) GetController(ID string) (*api.ReplicationControlle
|
|||||||
return &api.ReplicationController{}, r.Err
|
return &api.ReplicationController{}, r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ControllerRegistry) CreateController(controller api.ReplicationController) error {
|
func (r *ControllerRegistry) CreateController(controller *api.ReplicationController) error {
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ControllerRegistry) UpdateController(controller api.ReplicationController) error {
|
func (r *ControllerRegistry) UpdateController(controller *api.ReplicationController) error {
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,19 +68,19 @@ func (r *PodRegistry) GetPod(podId string) (*api.Pod, error) {
|
|||||||
return r.Pod, r.Err
|
return r.Pod, r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PodRegistry) CreatePod(pod api.Pod) error {
|
func (r *PodRegistry) CreatePod(pod *api.Pod) error {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
r.Pod = &pod
|
r.Pod = pod
|
||||||
r.mux.Action(watch.Added, &pod)
|
r.mux.Action(watch.Added, pod)
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PodRegistry) UpdatePod(pod api.Pod) error {
|
func (r *PodRegistry) UpdatePod(pod *api.Pod) error {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
r.Pod = &pod
|
r.Pod = pod
|
||||||
r.mux.Action(watch.Modified, &pod)
|
r.mux.Action(watch.Modified, pod)
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ func (r *ServiceRegistry) ListServices() (*api.ServiceList, error) {
|
|||||||
return &r.List, r.Err
|
return &r.List, r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ServiceRegistry) CreateService(svc api.Service) error {
|
func (r *ServiceRegistry) CreateService(svc *api.Service) error {
|
||||||
r.Service = &svc
|
r.Service = svc
|
||||||
r.List.Items = append(r.List.Items, svc)
|
r.List.Items = append(r.List.Items, *svc)
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ func (r *ServiceRegistry) DeleteService(id string) error {
|
|||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ServiceRegistry) UpdateService(svc api.Service) error {
|
func (r *ServiceRegistry) UpdateService(svc *api.Service) error {
|
||||||
r.UpdatedID = svc.ID
|
r.UpdatedID = svc.ID
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,8 @@ func (r *ServiceRegistry) GetEndpoints(id string) (*api.Endpoints, error) {
|
|||||||
return &r.Endpoints, r.Err
|
return &r.Endpoints, r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ServiceRegistry) UpdateEndpoints(e api.Endpoints) error {
|
func (r *ServiceRegistry) UpdateEndpoints(e *api.Endpoints) error {
|
||||||
r.Endpoints = e
|
r.Endpoints = *e
|
||||||
return r.Err
|
return r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ import (
|
|||||||
// Registry is an interface for things that know how to store services.
|
// Registry is an interface for things that know how to store services.
|
||||||
type Registry interface {
|
type Registry interface {
|
||||||
ListServices() (*api.ServiceList, error)
|
ListServices() (*api.ServiceList, error)
|
||||||
CreateService(svc api.Service) error
|
CreateService(svc *api.Service) error
|
||||||
GetService(name string) (*api.Service, error)
|
GetService(name string) (*api.Service, error)
|
||||||
DeleteService(name string) error
|
DeleteService(name string) error
|
||||||
UpdateService(svc api.Service) error
|
UpdateService(svc *api.Service) error
|
||||||
WatchServices(labels, fields labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
WatchServices(labels, fields labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
||||||
|
|
||||||
// TODO: endpoints and their implementation should be separated, setting endpoints should be
|
// TODO: endpoints and their implementation should be separated, setting endpoints should be
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
@@ -49,7 +50,7 @@ func NewRegistryStorage(registry Registry, cloud cloudprovider.Interface, machin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
srv := obj.(*api.Service)
|
srv := obj.(*api.Service)
|
||||||
if errs := validation.ValidateService(srv); len(errs) > 0 {
|
if errs := validation.ValidateService(srv); len(errs) > 0 {
|
||||||
return nil, errors.NewInvalid("service", srv.ID, errs)
|
return nil, errors.NewInvalid("service", srv.ID, errs)
|
||||||
@@ -57,7 +58,7 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
|
|
||||||
srv.CreationTimestamp = util.Now()
|
srv.CreationTimestamp = util.Now()
|
||||||
|
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
// TODO: Consider moving this to a rectification loop, so that we make/remove external load balancers
|
// TODO: Consider moving this to a rectification loop, so that we make/remove external load balancers
|
||||||
// correctly no matter what http operations happen.
|
// correctly no matter what http operations happen.
|
||||||
if srv.CreateExternalLoadBalancer {
|
if srv.CreateExternalLoadBalancer {
|
||||||
@@ -85,7 +86,7 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := rs.registry.CreateService(*srv)
|
err := rs.registry.CreateService(srv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -93,18 +94,18 @@ func (rs *RegistryStorage) Create(obj interface{}) (<-chan interface{}, error) {
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Delete(id string) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Delete(id string) (<-chan runtime.Object, error) {
|
||||||
service, err := rs.registry.GetService(id)
|
service, err := rs.registry.GetService(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
rs.deleteExternalLoadBalancer(service)
|
rs.deleteExternalLoadBalancer(service)
|
||||||
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeleteService(id)
|
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeleteService(id)
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
func (rs *RegistryStorage) Get(id string) (runtime.Object, error) {
|
||||||
s, err := rs.registry.GetService(id)
|
s, err := rs.registry.GetService(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -112,7 +113,7 @@ func (rs *RegistryStorage) Get(id string) (interface{}, error) {
|
|||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) List(selector labels.Selector) (interface{}, error) {
|
func (rs *RegistryStorage) List(selector labels.Selector) (runtime.Object, error) {
|
||||||
list, err := rs.registry.ListServices()
|
list, err := rs.registry.ListServices()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -133,7 +134,7 @@ func (rs *RegistryStorage) Watch(label, field labels.Selector, resourceVersion u
|
|||||||
return rs.registry.WatchServices(label, field, resourceVersion)
|
return rs.registry.WatchServices(label, field, resourceVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs RegistryStorage) New() interface{} {
|
func (rs RegistryStorage) New() runtime.Object {
|
||||||
return &api.Service{}
|
return &api.Service{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,14 +156,14 @@ func GetServiceEnvironmentVariables(registry Registry, machine string) ([]api.En
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RegistryStorage) Update(obj interface{}) (<-chan interface{}, error) {
|
func (rs *RegistryStorage) Update(obj runtime.Object) (<-chan runtime.Object, error) {
|
||||||
srv := obj.(*api.Service)
|
srv := obj.(*api.Service)
|
||||||
if errs := validation.ValidateService(srv); len(errs) > 0 {
|
if errs := validation.ValidateService(srv); len(errs) > 0 {
|
||||||
return nil, errors.NewInvalid("service", srv.ID, errs)
|
return nil, errors.NewInvalid("service", srv.ID, errs)
|
||||||
}
|
}
|
||||||
return apiserver.MakeAsync(func() (interface{}, error) {
|
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||||
// TODO: check to see if external load balancer status changed
|
// TODO: check to see if external load balancer status changed
|
||||||
err := rs.registry.UpdateService(*srv)
|
err := rs.registry.UpdateService(srv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
|
|||||||
|
|
||||||
func TestServiceRegistryUpdate(t *testing.T) {
|
func TestServiceRegistryUpdate(t *testing.T) {
|
||||||
registry := registrytest.NewServiceRegistry()
|
registry := registrytest.NewServiceRegistry()
|
||||||
registry.CreateService(api.Service{
|
registry.CreateService(&api.Service{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz1"},
|
Selector: map[string]string{"bar": "baz1"},
|
||||||
@@ -118,7 +118,7 @@ func TestServiceRegistryUpdate(t *testing.T) {
|
|||||||
|
|
||||||
func TestServiceStorageValidatesUpdate(t *testing.T) {
|
func TestServiceStorageValidatesUpdate(t *testing.T) {
|
||||||
registry := registrytest.NewServiceRegistry()
|
registry := registrytest.NewServiceRegistry()
|
||||||
registry.CreateService(api.Service{
|
registry.CreateService(&api.Service{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
@@ -200,7 +200,7 @@ func TestServiceRegistryDelete(t *testing.T) {
|
|||||||
fakeCloud := &cloud.FakeCloud{}
|
fakeCloud := &cloud.FakeCloud{}
|
||||||
machines := []string{"foo", "bar", "baz"}
|
machines := []string{"foo", "bar", "baz"}
|
||||||
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
||||||
svc := api.Service{
|
svc := &api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) {
|
|||||||
fakeCloud := &cloud.FakeCloud{}
|
fakeCloud := &cloud.FakeCloud{}
|
||||||
machines := []string{"foo", "bar", "baz"}
|
machines := []string{"foo", "bar", "baz"}
|
||||||
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
||||||
svc := api.Service{
|
svc := &api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
CreateExternalLoadBalancer: true,
|
CreateExternalLoadBalancer: true,
|
||||||
@@ -263,7 +263,7 @@ func TestServiceRegistryGet(t *testing.T) {
|
|||||||
fakeCloud := &cloud.FakeCloud{}
|
fakeCloud := &cloud.FakeCloud{}
|
||||||
machines := []string{"foo", "bar", "baz"}
|
machines := []string{"foo", "bar", "baz"}
|
||||||
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
||||||
registry.CreateService(api.Service{
|
registry.CreateService(&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
})
|
})
|
||||||
@@ -282,7 +282,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
|
|||||||
fakeCloud := &cloud.FakeCloud{}
|
fakeCloud := &cloud.FakeCloud{}
|
||||||
machines := []string{"foo", "bar", "baz"}
|
machines := []string{"foo", "bar", "baz"}
|
||||||
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
||||||
registry.CreateService(api.Service{
|
registry.CreateService(&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
})
|
})
|
||||||
@@ -310,11 +310,11 @@ func TestServiceRegistryList(t *testing.T) {
|
|||||||
fakeCloud := &cloud.FakeCloud{}
|
fakeCloud := &cloud.FakeCloud{}
|
||||||
machines := []string{"foo", "bar", "baz"}
|
machines := []string{"foo", "bar", "baz"}
|
||||||
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
storage := NewRegistryStorage(registry, fakeCloud, minion.NewRegistry(machines))
|
||||||
registry.CreateService(api.Service{
|
registry.CreateService(&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
})
|
})
|
||||||
registry.CreateService(api.Service{
|
registry.CreateService(&api.Service{
|
||||||
JSONBase: api.JSONBase{ID: "foo2"},
|
JSONBase: api.JSONBase{ID: "foo2"},
|
||||||
Selector: map[string]string{"bar2": "baz2"},
|
Selector: map[string]string{"bar2": "baz2"},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := Decode(b)
|
obj, err := DefaultCodec.Decode(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
|
|||||||
return []byte("null"), nil
|
return []byte("null"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return Encode(a.Object)
|
return DefaultCodec.Encode(a.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetYAML implements the yaml.Setter interface.
|
// SetYAML implements the yaml.Setter interface.
|
||||||
@@ -67,7 +67,7 @@ func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic("yaml can't reverse its own object")
|
panic("yaml can't reverse its own object")
|
||||||
}
|
}
|
||||||
obj, err := Decode(b)
|
obj, err := DefaultCodec.Decode(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Encode returns JSON, which is conveniently a subset of YAML.
|
// Encode returns JSON, which is conveniently a subset of YAML.
|
||||||
v, err := Encode(a.Object)
|
v, err := DefaultCodec.Encode(a.Object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("impossible to encode API object!")
|
panic("impossible to encode API object!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,19 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type EmbeddedTest struct {
|
||||||
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
|
Object EmbeddedObject `yaml:"object,omitempty" json:"object,omitempty"`
|
||||||
|
EmptyObject EmbeddedObject `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*EmbeddedTest) IsAnAPIObject() {}
|
||||||
|
|
||||||
func TestEmbeddedObject(t *testing.T) {
|
func TestEmbeddedObject(t *testing.T) {
|
||||||
type EmbeddedTest struct {
|
// TODO(dbsmith) fix EmbeddedObject to not use DefaultScheme.
|
||||||
JSONBase `yaml:",inline" json:",inline"`
|
s := DefaultScheme
|
||||||
Object EmbeddedObject `yaml:"object,omitempty" json:"object,omitempty"`
|
s.AddKnownTypes("", &EmbeddedTest{})
|
||||||
EmptyObject EmbeddedObject `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
|
s.AddKnownTypes("v1beta1", &EmbeddedTest{})
|
||||||
}
|
|
||||||
AddKnownTypes("", EmbeddedTest{})
|
|
||||||
AddKnownTypes("v1beta1", EmbeddedTest{})
|
|
||||||
|
|
||||||
outer := &EmbeddedTest{
|
outer := &EmbeddedTest{
|
||||||
JSONBase: JSONBase{ID: "outer"},
|
JSONBase: JSONBase{ID: "outer"},
|
||||||
@@ -40,14 +45,14 @@ func TestEmbeddedObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
wire, err := Encode(outer)
|
wire, err := s.Encode(outer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected encode error '%v'", err)
|
t.Fatalf("Unexpected encode error '%v'", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("Wire format is:\n%v\n", string(wire))
|
t.Logf("Wire format is:\n%v\n", string(wire))
|
||||||
|
|
||||||
decoded, err := Decode(wire)
|
decoded, err := s.Decode(wire)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected decode error %v", err)
|
t.Fatalf("Unexpected decode error %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,41 +24,44 @@ import (
|
|||||||
"gopkg.in/v1/yaml"
|
"gopkg.in/v1/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// codec defines methods for serializing and deserializing API
|
var DefaultResourceVersioner ResourceVersioner = NewJSONBaseResourceVersioner()
|
||||||
// objects.
|
var DefaultScheme = NewScheme("", "v1beta1")
|
||||||
type codec interface {
|
var DefaultCodec Codec = DefaultScheme
|
||||||
Encode(obj interface{}) (data []byte, err error)
|
|
||||||
Decode(data []byte) (interface{}, error)
|
// Scheme defines methods for serializing and deserializing API objects. It
|
||||||
DecodeInto(data []byte, obj interface{}) error
|
// is an adaptation of conversion's Scheme for our API objects.
|
||||||
|
type Scheme struct {
|
||||||
|
raw *conversion.Scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourceVersioner provides methods for setting and retrieving
|
// NewScheme creates a new Scheme. A default scheme is provided and accessible
|
||||||
// the resource version from an API object.
|
// as the "DefaultScheme" variable.
|
||||||
type resourceVersioner interface {
|
func NewScheme(internalVersion, externalVersion string) *Scheme {
|
||||||
SetResourceVersion(obj interface{}, version uint64) error
|
s := &Scheme{conversion.NewScheme()}
|
||||||
ResourceVersion(obj interface{}) (uint64, error)
|
s.raw.InternalVersion = internalVersion
|
||||||
}
|
s.raw.ExternalVersion = externalVersion
|
||||||
|
s.raw.MetaInsertionFactory = metaInsertion{}
|
||||||
var ResourceVersioner resourceVersioner = NewJSONBaseResourceVersioner()
|
return s
|
||||||
var conversionScheme = conversion.NewScheme()
|
|
||||||
var Codec codec = conversionScheme
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
conversionScheme.InternalVersion = ""
|
|
||||||
conversionScheme.ExternalVersion = "v1beta1"
|
|
||||||
conversionScheme.MetaInsertionFactory = metaInsertion{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddKnownTypes registers the types of the arguments to the marshaller of the package api.
|
// AddKnownTypes registers the types of the arguments to the marshaller of the package api.
|
||||||
// Encode() refuses the object unless its type is registered with AddKnownTypes.
|
// Encode() refuses the object unless its type is registered with AddKnownTypes.
|
||||||
func AddKnownTypes(version string, types ...interface{}) {
|
func (s *Scheme) AddKnownTypes(version string, types ...Object) {
|
||||||
conversionScheme.AddKnownTypes(version, types...)
|
interfaces := make([]interface{}, len(types))
|
||||||
|
for i := range types {
|
||||||
|
interfaces[i] = types[i]
|
||||||
|
}
|
||||||
|
s.raw.AddKnownTypes(version, interfaces...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new API object of the given version ("" for internal
|
// New returns a new API object of the given version ("" for internal
|
||||||
// representation) and name, or an error if it hasn't been registered.
|
// representation) and name, or an error if it hasn't been registered.
|
||||||
func New(versionName, typeName string) (interface{}, error) {
|
func (s *Scheme) New(versionName, typeName string) (Object, error) {
|
||||||
return conversionScheme.NewObject(versionName, typeName)
|
obj, err := s.raw.NewObject(versionName, typeName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj.(Object), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddConversionFuncs adds a function to the list of conversion functions. The given
|
// AddConversionFuncs adds a function to the list of conversion functions. The given
|
||||||
@@ -73,20 +76,20 @@ func New(versionName, typeName string) (interface{}, error) {
|
|||||||
// sanely copy fields that have the same names. It's OK if the destination type has
|
// sanely copy fields that have the same names. It's OK if the destination type has
|
||||||
// extra fields, but it must not remove any. So you only need to add a conversion
|
// extra fields, but it must not remove any. So you only need to add a conversion
|
||||||
// function for things with changed/removed fields.
|
// function for things with changed/removed fields.
|
||||||
func AddConversionFuncs(conversionFuncs ...interface{}) error {
|
func (s *Scheme) AddConversionFuncs(conversionFuncs ...interface{}) error {
|
||||||
return conversionScheme.AddConversionFuncs(conversionFuncs...)
|
return s.raw.AddConversionFuncs(conversionFuncs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert will attempt to convert in into out. Both must be pointers to API objects.
|
// Convert will attempt to convert in into out. Both must be pointers.
|
||||||
// For easy testing of conversion functions. Returns an error if the conversion isn't
|
// For easy testing of conversion functions. Returns an error if the conversion isn't
|
||||||
// possible.
|
// possible.
|
||||||
func Convert(in, out interface{}) error {
|
func (s *Scheme) Convert(in, out interface{}) error {
|
||||||
return conversionScheme.Convert(in, out)
|
return s.raw.Convert(in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindJSONBase takes an arbitary api type, returns pointer to its JSONBase field.
|
// FindJSONBase takes an arbitary api type, returns pointer to its JSONBase field.
|
||||||
// obj must be a pointer to an api type.
|
// obj must be a pointer to an api type.
|
||||||
func FindJSONBase(obj interface{}) (JSONBaseInterface, error) {
|
func FindJSONBase(obj Object) (JSONBaseInterface, error) {
|
||||||
v, err := enforcePtr(obj)
|
v, err := enforcePtr(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -108,8 +111,8 @@ func FindJSONBase(obj interface{}) (JSONBaseInterface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
|
// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
|
||||||
func EncodeOrDie(obj interface{}) string {
|
func (s *Scheme) EncodeOrDie(obj Object) string {
|
||||||
return conversionScheme.EncodeOrDie(obj)
|
return s.raw.EncodeOrDie(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode turns the given api object into an appropriate JSON string.
|
// Encode turns the given api object into an appropriate JSON string.
|
||||||
@@ -146,14 +149,14 @@ func EncodeOrDie(obj interface{}) string {
|
|||||||
// default will be needed, to allow operating in clusters that haven't yet
|
// default will be needed, to allow operating in clusters that haven't yet
|
||||||
// upgraded.
|
// upgraded.
|
||||||
//
|
//
|
||||||
func Encode(obj interface{}) (data []byte, err error) {
|
func (s *Scheme) Encode(obj Object) (data []byte, err error) {
|
||||||
return conversionScheme.Encode(obj)
|
return s.raw.Encode(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforcePtr ensures that obj is a pointer of some sort. Returns a reflect.Value of the
|
// enforcePtr ensures that obj is a pointer of some sort. Returns a reflect.Value of the
|
||||||
// dereferenced pointer, ensuring that it is settable/addressable.
|
// dereferenced pointer, ensuring that it is settable/addressable.
|
||||||
// Returns an error if this is not possible.
|
// Returns an error if this is not possible.
|
||||||
func enforcePtr(obj interface{}) (reflect.Value, error) {
|
func enforcePtr(obj Object) (reflect.Value, error) {
|
||||||
v := reflect.ValueOf(obj)
|
v := reflect.ValueOf(obj)
|
||||||
if v.Kind() != reflect.Ptr {
|
if v.Kind() != reflect.Ptr {
|
||||||
return reflect.Value{}, fmt.Errorf("expected pointer, but got %v", v.Type().Name())
|
return reflect.Value{}, fmt.Errorf("expected pointer, but got %v", v.Type().Name())
|
||||||
@@ -181,8 +184,12 @@ func VersionAndKind(data []byte) (version, kind string, err error) {
|
|||||||
// Deduces the type based upon the APIVersion and Kind fields, which are set
|
// Deduces the type based upon the APIVersion and Kind fields, which are set
|
||||||
// by Encode. Only versioned objects (APIVersion != "") are accepted. The object
|
// by Encode. Only versioned objects (APIVersion != "") are accepted. The object
|
||||||
// will be converted into the in-memory unversioned type before being returned.
|
// will be converted into the in-memory unversioned type before being returned.
|
||||||
func Decode(data []byte) (interface{}, error) {
|
func (s *Scheme) Decode(data []byte) (Object, error) {
|
||||||
return conversionScheme.Decode(data)
|
obj, err := s.raw.Decode(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj.(Object), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeInto parses a YAML or JSON string and stores it in obj. Returns an error
|
// DecodeInto parses a YAML or JSON string and stores it in obj. Returns an error
|
||||||
@@ -190,22 +197,22 @@ func Decode(data []byte) (interface{}, error) {
|
|||||||
// pointer to an api type.
|
// pointer to an api type.
|
||||||
// If obj's APIVersion doesn't match that in data, an attempt will be made to convert
|
// If obj's APIVersion doesn't match that in data, an attempt will be made to convert
|
||||||
// data into obj's version.
|
// data into obj's version.
|
||||||
func DecodeInto(data []byte, obj interface{}) error {
|
func (s *Scheme) DecodeInto(data []byte, obj Object) error {
|
||||||
return conversionScheme.DecodeInto(data, obj)
|
return s.raw.DecodeInto(data, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does a deep copy of an API object. Useful mostly for tests.
|
// Does a deep copy of an API object. Useful mostly for tests.
|
||||||
// TODO(dbsmith): implement directly instead of via Encode/Decode
|
// TODO(dbsmith): implement directly instead of via Encode/Decode
|
||||||
func Copy(obj interface{}) (interface{}, error) {
|
func (s *Scheme) Copy(obj Object) (Object, error) {
|
||||||
data, err := Encode(obj)
|
data, err := s.Encode(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return Decode(data)
|
return s.Decode(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CopyOrDie(obj interface{}) interface{} {
|
func (s *Scheme) CopyOrDie(obj Object) Object {
|
||||||
newObj, err := Copy(obj)
|
newObj, err := s.Copy(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,31 +25,13 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEncode_NonPtr(t *testing.T) {
|
func TestEncode(t *testing.T) {
|
||||||
pod := api.Pod{
|
|
||||||
Labels: map[string]string{"name": "foo"},
|
|
||||||
}
|
|
||||||
obj := interface{}(pod)
|
|
||||||
data, err := runtime.Encode(obj)
|
|
||||||
obj2, err2 := runtime.Decode(data)
|
|
||||||
if err != nil || err2 != nil {
|
|
||||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
|
||||||
}
|
|
||||||
if _, ok := obj2.(*api.Pod); !ok {
|
|
||||||
t.Fatalf("Got wrong type")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(obj2, &pod) {
|
|
||||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", &pod, obj2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEncode_Ptr(t *testing.T) {
|
|
||||||
pod := &api.Pod{
|
pod := &api.Pod{
|
||||||
Labels: map[string]string{"name": "foo"},
|
Labels: map[string]string{"name": "foo"},
|
||||||
}
|
}
|
||||||
obj := interface{}(pod)
|
obj := runtime.Object(pod)
|
||||||
data, err := runtime.Encode(obj)
|
data, err := runtime.DefaultScheme.Encode(obj)
|
||||||
obj2, err2 := runtime.Decode(data)
|
obj2, err2 := runtime.DefaultScheme.Decode(data)
|
||||||
if err != nil || err2 != nil {
|
if err != nil || err2 != nil {
|
||||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||||
}
|
}
|
||||||
@@ -63,11 +45,11 @@ func TestEncode_Ptr(t *testing.T) {
|
|||||||
|
|
||||||
func TestBadJSONRejection(t *testing.T) {
|
func TestBadJSONRejection(t *testing.T) {
|
||||||
badJSONMissingKind := []byte(`{ }`)
|
badJSONMissingKind := []byte(`{ }`)
|
||||||
if _, err := runtime.Decode(badJSONMissingKind); err == nil {
|
if _, err := runtime.DefaultScheme.Decode(badJSONMissingKind); err == nil {
|
||||||
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
||||||
}
|
}
|
||||||
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
||||||
if _, err1 := runtime.Decode(badJSONUnknownType); err1 == nil {
|
if _, err1 := runtime.DefaultScheme.Decode(badJSONUnknownType); err1 == nil {
|
||||||
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
||||||
}
|
}
|
||||||
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
||||||
|
|||||||
40
pkg/runtime/interfaces.go
Normal file
40
pkg/runtime/interfaces.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
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 runtime
|
||||||
|
|
||||||
|
// Codec defines methods for serializing and deserializing API objects.
|
||||||
|
type Codec interface {
|
||||||
|
Encode(obj Object) (data []byte, err error)
|
||||||
|
Decode(data []byte) (Object, error)
|
||||||
|
DecodeInto(data []byte, obj Object) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceVersioner provides methods for setting and retrieving
|
||||||
|
// the resource version from an API object.
|
||||||
|
type ResourceVersioner interface {
|
||||||
|
SetResourceVersion(obj Object, version uint64) error
|
||||||
|
ResourceVersion(obj Object) (uint64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// All api types must support the Object interface. It's deliberately tiny so that this is not an onerous
|
||||||
|
// burden. Implement it with a pointer reciever; this will allow us to use the go compiler to check the
|
||||||
|
// one thing about our objects that it's capable of checking for us.
|
||||||
|
type Object interface {
|
||||||
|
// This function is used only to enforce membership. It's never called.
|
||||||
|
// TODO: Consider mass rename in the future to make it do something useful.
|
||||||
|
IsAnAPIObject()
|
||||||
|
}
|
||||||
@@ -23,13 +23,13 @@ import (
|
|||||||
|
|
||||||
// NewJSONBaseResourceVersioner returns a resourceVersioner that can set or
|
// NewJSONBaseResourceVersioner returns a resourceVersioner that can set or
|
||||||
// retrieve ResourceVersion on objects derived from JSONBase.
|
// retrieve ResourceVersion on objects derived from JSONBase.
|
||||||
func NewJSONBaseResourceVersioner() resourceVersioner {
|
func NewJSONBaseResourceVersioner() ResourceVersioner {
|
||||||
return &jsonBaseResourceVersioner{}
|
return &jsonBaseResourceVersioner{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonBaseResourceVersioner struct{}
|
type jsonBaseResourceVersioner struct{}
|
||||||
|
|
||||||
func (v jsonBaseResourceVersioner) ResourceVersion(obj interface{}) (uint64, error) {
|
func (v jsonBaseResourceVersioner) ResourceVersion(obj Object) (uint64, error) {
|
||||||
json, err := FindJSONBase(obj)
|
json, err := FindJSONBase(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -37,7 +37,7 @@ func (v jsonBaseResourceVersioner) ResourceVersion(obj interface{}) (uint64, err
|
|||||||
return json.ResourceVersion(), nil
|
return json.ResourceVersion(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v jsonBaseResourceVersioner) SetResourceVersion(obj interface{}, version uint64) error {
|
func (v jsonBaseResourceVersioner) SetResourceVersion(obj Object, version uint64) error {
|
||||||
json, err := FindJSONBase(obj)
|
json, err := FindJSONBase(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -77,20 +77,20 @@ func TestGenericJSONBase(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MyAPIObject struct {
|
||||||
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*MyAPIObject) IsAnAPIObject() {}
|
||||||
|
|
||||||
|
type MyIncorrectlyMarkedAsAPIObject struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*MyIncorrectlyMarkedAsAPIObject) IsAnAPIObject() {}
|
||||||
|
|
||||||
func TestResourceVersionerOfAPI(t *testing.T) {
|
func TestResourceVersionerOfAPI(t *testing.T) {
|
||||||
type JSONBase struct {
|
|
||||||
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
|
|
||||||
ID string `json:"id,omitempty" yaml:"id,omitempty"`
|
|
||||||
CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"`
|
|
||||||
SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
|
|
||||||
ResourceVersion uint64 `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"`
|
|
||||||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
|
||||||
}
|
|
||||||
type MyAPIObject struct {
|
|
||||||
JSONBase `yaml:",inline" json:",inline"`
|
|
||||||
}
|
|
||||||
type T struct {
|
type T struct {
|
||||||
Object interface{}
|
Object
|
||||||
Expected uint64
|
Expected uint64
|
||||||
}
|
}
|
||||||
testCases := map[string]T{
|
testCases := map[string]T{
|
||||||
@@ -110,10 +110,10 @@ func TestResourceVersionerOfAPI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
failingCases := map[string]struct {
|
failingCases := map[string]struct {
|
||||||
Object interface{}
|
Object
|
||||||
Expected uint64
|
Expected uint64
|
||||||
}{
|
}{
|
||||||
"not a valid object to try": {JSONBase{ResourceVersion: 1}, 1},
|
"not a valid object to try": {&MyIncorrectlyMarkedAsAPIObject{}, 1},
|
||||||
}
|
}
|
||||||
for key, testCase := range failingCases {
|
for key, testCase := range failingCases {
|
||||||
_, err := versioning.ResourceVersion(testCase.Object)
|
_, err := versioning.ResourceVersion(testCase.Object)
|
||||||
@@ -123,7 +123,7 @@ func TestResourceVersionerOfAPI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCases := map[string]struct {
|
setCases := map[string]struct {
|
||||||
Object interface{}
|
Object
|
||||||
Expected uint64
|
Expected uint64
|
||||||
}{
|
}{
|
||||||
"pointer to api object with version": {&MyAPIObject{JSONBase: JSONBase{ResourceVersion: 1}}, 1},
|
"pointer to api object with version": {&MyAPIObject{JSONBase: JSONBase{ResourceVersion: 1}}, 1},
|
||||||
@@ -140,17 +140,4 @@ func TestResourceVersionerOfAPI(t *testing.T) {
|
|||||||
t.Errorf("%s: expected %d, got %d", key, 5, actual)
|
t.Errorf("%s: expected %d, got %d", key, 5, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
failingSetCases := map[string]struct {
|
|
||||||
Object interface{}
|
|
||||||
Expected uint64
|
|
||||||
}{
|
|
||||||
"empty api object": {MyAPIObject{}, 0},
|
|
||||||
"api object with version": {MyAPIObject{JSONBase: JSONBase{ResourceVersion: 1}}, 1},
|
|
||||||
}
|
|
||||||
for key, testCase := range failingSetCases {
|
|
||||||
if err := versioning.SetResourceVersion(testCase.Object, 5); err == nil {
|
|
||||||
t.Errorf("%s: unexpected non-error", key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ import (
|
|||||||
// runtime.JSONBase `yaml:",inline" json:",inline"`
|
// runtime.JSONBase `yaml:",inline" json:",inline"`
|
||||||
// ... // other fields
|
// ... // other fields
|
||||||
// }
|
// }
|
||||||
|
// func (*MyAwesomeAPIObject) IsAnAPIObject() {}
|
||||||
//
|
//
|
||||||
// JSONBase is provided here for convenience. You may use it directlly from this package or define
|
// JSONBase is provided here for convenience. You may use it directly from this package or define
|
||||||
// your own with the same fields.
|
// your own with the same fields.
|
||||||
//
|
//
|
||||||
type JSONBase struct {
|
type JSONBase struct {
|
||||||
@@ -43,17 +44,16 @@ type JSONBase struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EmbeddedObject has appropriate encoder and decoder functions, such that on the wire, it's
|
// EmbeddedObject has 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 interface{}
|
// stored as a []byte, but in memory, the contained object is accessable as an Object
|
||||||
// via the Get() function. Only objects having a JSONBase may be stored via 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
|
// The purpose of this is to allow an API object of type known only at runtime to be
|
||||||
// embedded within other API objects.
|
// embedded within other API objects.
|
||||||
//
|
//
|
||||||
// Note that object assumes that you've registered all of your api types with the api package.
|
// Note that object assumes that you've registered all of your api types with the api package.
|
||||||
//
|
//
|
||||||
// Note that objects will be serialized into the api package's default external versioned type;
|
// TODO(dbsmith): Stop using runtime.Codec, use the codec appropriate for the conversion (I have a plan).
|
||||||
// this should be fixed in the future to use the version of the current Codec instead.
|
|
||||||
type EmbeddedObject struct {
|
type EmbeddedObject struct {
|
||||||
Object interface{}
|
Object
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extension allows api objects with unknown types to be passed-through. This can be used
|
// Extension allows api objects with unknown types to be passed-through. This can be used
|
||||||
@@ -61,4 +61,8 @@ type EmbeddedObject struct {
|
|||||||
// JSONBase features-- kind, version, resourceVersion, etc.
|
// JSONBase features-- kind, version, resourceVersion, etc.
|
||||||
// TODO: Not implemented yet
|
// TODO: Not implemented yet
|
||||||
type Extension struct {
|
type Extension struct {
|
||||||
|
JSONBase `yaml:",inline" json:",inline"`
|
||||||
|
// RawJSON to go here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Extension) IsAnAPIObject() {}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func (e *EndpointController) SyncServiceEndpoints() error {
|
|||||||
endpoints[ix] = net.JoinHostPort(pod.CurrentState.PodIP, strconv.Itoa(port))
|
endpoints[ix] = net.JoinHostPort(pod.CurrentState.PodIP, strconv.Itoa(port))
|
||||||
}
|
}
|
||||||
// TODO: this is totally broken, we need to compute this and store inside an AtomicUpdate loop.
|
// TODO: this is totally broken, we need to compute this and store inside an AtomicUpdate loop.
|
||||||
err = e.serviceRegistry.UpdateEndpoints(api.Endpoints{
|
err = e.serviceRegistry.UpdateEndpoints(&api.Endpoints{
|
||||||
JSONBase: api.JSONBase{ID: service.ID},
|
JSONBase: api.JSONBase{ID: service.ID},
|
||||||
Endpoints: endpoints,
|
Endpoints: endpoints,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ func NewAPIEventDecoder(stream io.ReadCloser) *APIEventDecoder {
|
|||||||
|
|
||||||
// Decode blocks until it can return the next object in the stream. Returns an error
|
// Decode blocks until it can return the next object in the stream. Returns an error
|
||||||
// if the stream is closed or an object can't be decoded.
|
// if the stream is closed or an object can't be decoded.
|
||||||
func (d *APIEventDecoder) Decode() (action watch.EventType, object interface{}, err error) {
|
func (d *APIEventDecoder) Decode() (action watch.EventType, object runtime.Object, err error) {
|
||||||
var got api.WatchEvent
|
var got api.WatchEvent
|
||||||
err = d.decoder.Decode(&got)
|
err = d.decoder.Decode(&got)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/coreos/go-etcd/etcd"
|
"github.com/coreos/go-etcd/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,19 +39,6 @@ var (
|
|||||||
EtcdErrorValueRequired = &etcd.EtcdError{ErrorCode: EtcdErrorCodeValueRequired}
|
EtcdErrorValueRequired = &etcd.EtcdError{ErrorCode: EtcdErrorCodeValueRequired}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Codec provides methods for transforming Etcd values into objects and back.
|
|
||||||
type Codec interface {
|
|
||||||
Encode(obj interface{}) (data []byte, err error)
|
|
||||||
Decode(data []byte) (interface{}, error)
|
|
||||||
DecodeInto(data []byte, obj interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceVersioner provides methods for managing object modification tracking.
|
|
||||||
type ResourceVersioner interface {
|
|
||||||
SetResourceVersion(obj interface{}, version uint64) error
|
|
||||||
ResourceVersion(obj interface{}) (uint64, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EtcdClient is an injectable interface for testing.
|
// EtcdClient is an injectable interface for testing.
|
||||||
type EtcdClient interface {
|
type EtcdClient interface {
|
||||||
AddChild(key, data string, ttl uint64) (*etcd.Response, error)
|
AddChild(key, data string, ttl uint64) (*etcd.Response, error)
|
||||||
@@ -77,9 +65,9 @@ type EtcdGetSet interface {
|
|||||||
// EtcdHelper offers common object marshalling/unmarshalling operations on an etcd client.
|
// EtcdHelper offers common object marshalling/unmarshalling operations on an etcd client.
|
||||||
type EtcdHelper struct {
|
type EtcdHelper struct {
|
||||||
Client EtcdGetSet
|
Client EtcdGetSet
|
||||||
Codec Codec
|
Codec runtime.Codec
|
||||||
// optional, no atomic operations can be performed without this interface
|
// optional, no atomic operations can be performed without this interface
|
||||||
ResourceVersioner ResourceVersioner
|
ResourceVersioner runtime.ResourceVersioner
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEtcdNotFound returns true iff err is an etcd not found error.
|
// IsEtcdNotFound returns true iff err is an etcd not found error.
|
||||||
@@ -151,9 +139,9 @@ func (h *EtcdHelper) ExtractList(key string, slicePtr interface{}, resourceVersi
|
|||||||
v := pv.Elem()
|
v := pv.Elem()
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
obj := reflect.New(v.Type().Elem())
|
obj := reflect.New(v.Type().Elem())
|
||||||
err = h.Codec.DecodeInto([]byte(node.Value), obj.Interface())
|
err = h.Codec.DecodeInto([]byte(node.Value), obj.Interface().(runtime.Object))
|
||||||
if h.ResourceVersioner != nil {
|
if h.ResourceVersioner != nil {
|
||||||
_ = h.ResourceVersioner.SetResourceVersion(obj.Interface(), node.ModifiedIndex)
|
_ = h.ResourceVersioner.SetResourceVersion(obj.Interface().(runtime.Object), node.ModifiedIndex)
|
||||||
// being unable to set the version does not prevent the object from being extracted
|
// being unable to set the version does not prevent the object from being extracted
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -167,12 +155,12 @@ func (h *EtcdHelper) ExtractList(key string, slicePtr interface{}, resourceVersi
|
|||||||
// ExtractObj unmarshals json found at key into objPtr. On a not found error, will either return
|
// ExtractObj unmarshals json found at key into objPtr. On a not found error, will either return
|
||||||
// a zero object of the requested type, or an error, depending on ignoreNotFound. Treats
|
// a zero object of the requested type, or an error, depending on ignoreNotFound. Treats
|
||||||
// empty responses and nil response nodes exactly like a not found error.
|
// empty responses and nil response nodes exactly like a not found error.
|
||||||
func (h *EtcdHelper) ExtractObj(key string, objPtr interface{}, ignoreNotFound bool) error {
|
func (h *EtcdHelper) ExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) error {
|
||||||
_, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound)
|
_, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *EtcdHelper) bodyAndExtractObj(key string, objPtr interface{}, ignoreNotFound bool) (body string, modifiedIndex uint64, err error) {
|
func (h *EtcdHelper) bodyAndExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) (body string, modifiedIndex uint64, err error) {
|
||||||
response, err := h.Client.Get(key, false, false)
|
response, err := h.Client.Get(key, false, false)
|
||||||
|
|
||||||
if err != nil && !IsEtcdNotFound(err) {
|
if err != nil && !IsEtcdNotFound(err) {
|
||||||
@@ -198,7 +186,7 @@ func (h *EtcdHelper) bodyAndExtractObj(key string, objPtr interface{}, ignoreNot
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateObj adds a new object at a key unless it already exists.
|
// CreateObj adds a new object at a key unless it already exists.
|
||||||
func (h *EtcdHelper) CreateObj(key string, obj interface{}) error {
|
func (h *EtcdHelper) CreateObj(key string, obj runtime.Object) error {
|
||||||
data, err := h.Codec.Encode(obj)
|
data, err := h.Codec.Encode(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -221,7 +209,7 @@ func (h *EtcdHelper) Delete(key string, recursive bool) error {
|
|||||||
|
|
||||||
// SetObj marshals obj via json, and stores under key. Will do an
|
// SetObj marshals obj via json, and stores under key. Will do an
|
||||||
// atomic update if obj's ResourceVersion field is set.
|
// atomic update if obj's ResourceVersion field is set.
|
||||||
func (h *EtcdHelper) SetObj(key string, obj interface{}) error {
|
func (h *EtcdHelper) SetObj(key string, obj runtime.Object) error {
|
||||||
data, err := h.Codec.Encode(obj)
|
data, err := h.Codec.Encode(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -240,7 +228,7 @@ func (h *EtcdHelper) SetObj(key string, obj interface{}) error {
|
|||||||
|
|
||||||
// Pass an EtcdUpdateFunc to EtcdHelper.AtomicUpdate to make an atomic etcd update.
|
// Pass an EtcdUpdateFunc to EtcdHelper.AtomicUpdate to make an atomic etcd update.
|
||||||
// See the comment for AtomicUpdate for more detail.
|
// See the comment for AtomicUpdate for more detail.
|
||||||
type EtcdUpdateFunc func(input interface{}) (output interface{}, err error)
|
type EtcdUpdateFunc func(input runtime.Object) (output runtime.Object, err error)
|
||||||
|
|
||||||
// AtomicUpdate generalizes the pattern that allows for making atomic updates to etcd objects.
|
// AtomicUpdate generalizes the pattern that allows for making atomic updates to etcd objects.
|
||||||
// Note, tryUpdate may be called more than once.
|
// Note, tryUpdate may be called more than once.
|
||||||
@@ -248,7 +236,7 @@ type EtcdUpdateFunc func(input interface{}) (output interface{}, err error)
|
|||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// h := &util.EtcdHelper{client, encoding, versioning}
|
// h := &util.EtcdHelper{client, encoding, versioning}
|
||||||
// err := h.AtomicUpdate("myKey", &MyType{}, func(input interface{}) (interface{}, error) {
|
// err := h.AtomicUpdate("myKey", &MyType{}, func(input runtime.Object) (runtime.Object, error) {
|
||||||
// // Before this function is called, currentObj has been reset to etcd's current
|
// // Before this function is called, currentObj has been reset to etcd's current
|
||||||
// // contents for "myKey".
|
// // contents for "myKey".
|
||||||
//
|
//
|
||||||
@@ -261,14 +249,14 @@ type EtcdUpdateFunc func(input interface{}) (output interface{}, err error)
|
|||||||
// return cur, nil
|
// return cur, nil
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
func (h *EtcdHelper) AtomicUpdate(key string, ptrToType interface{}, tryUpdate EtcdUpdateFunc) error {
|
func (h *EtcdHelper) AtomicUpdate(key string, ptrToType runtime.Object, tryUpdate EtcdUpdateFunc) error {
|
||||||
pt := reflect.TypeOf(ptrToType)
|
pt := reflect.TypeOf(ptrToType)
|
||||||
if pt.Kind() != reflect.Ptr {
|
if pt.Kind() != reflect.Ptr {
|
||||||
// Panic is appropriate, because this is a programming error.
|
// Panic is appropriate, because this is a programming error.
|
||||||
panic("need ptr to type")
|
panic("need ptr to type")
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
obj := reflect.New(pt.Elem()).Interface()
|
obj := reflect.New(pt.Elem()).Interface().(runtime.Object)
|
||||||
origBody, index, err := h.bodyAndExtractObj(key, obj, true)
|
origBody, index, err := h.bodyAndExtractObj(key, obj, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/coreos/go-etcd/etcd"
|
"github.com/coreos/go-etcd/etcd"
|
||||||
@@ -40,15 +39,16 @@ type TestResource struct {
|
|||||||
Value int `json:"value" yaml:"value,omitempty"`
|
Value int `json:"value" yaml:"value,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var scheme *conversion.Scheme
|
func (*TestResource) IsAnAPIObject() {}
|
||||||
var codec = runtime.Codec
|
|
||||||
var versioner = runtime.ResourceVersioner
|
var scheme *runtime.Scheme
|
||||||
|
var codec = runtime.DefaultCodec
|
||||||
|
var versioner = runtime.DefaultResourceVersioner
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
scheme = conversion.NewScheme()
|
scheme = runtime.NewScheme("", "v1beta1")
|
||||||
scheme.ExternalVersion = "v1beta1"
|
scheme.AddKnownTypes("", &TestResource{})
|
||||||
scheme.AddKnownTypes("", TestResource{})
|
scheme.AddKnownTypes("v1beta1", &TestResource{})
|
||||||
scheme.AddKnownTypes("v1beta1", TestResource{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsEtcdNotFound(t *testing.T) {
|
func TestIsEtcdNotFound(t *testing.T) {
|
||||||
@@ -166,7 +166,7 @@ func TestExtractObjNotFoundErr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetObj(t *testing.T) {
|
func TestSetObj(t *testing.T) {
|
||||||
obj := api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
obj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
fakeClient := NewFakeEtcdClient(t)
|
fakeClient := NewFakeEtcdClient(t)
|
||||||
helper := EtcdHelper{fakeClient, codec, versioner}
|
helper := EtcdHelper{fakeClient, codec, versioner}
|
||||||
err := helper.SetObj("/some/key", obj)
|
err := helper.SetObj("/some/key", obj)
|
||||||
@@ -191,7 +191,7 @@ func TestSetObjWithVersion(t *testing.T) {
|
|||||||
fakeClient.Data["/some/key"] = EtcdResponseWithError{
|
fakeClient.Data["/some/key"] = EtcdResponseWithError{
|
||||||
R: &etcd.Response{
|
R: &etcd.Response{
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: runtime.EncodeOrDie(obj),
|
Value: runtime.DefaultScheme.EncodeOrDie(obj),
|
||||||
ModifiedIndex: 1,
|
ModifiedIndex: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -214,7 +214,7 @@ func TestSetObjWithVersion(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetObjWithoutResourceVersioner(t *testing.T) {
|
func TestSetObjWithoutResourceVersioner(t *testing.T) {
|
||||||
obj := api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
obj := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
fakeClient := NewFakeEtcdClient(t)
|
fakeClient := NewFakeEtcdClient(t)
|
||||||
helper := EtcdHelper{fakeClient, codec, nil}
|
helper := EtcdHelper{fakeClient, codec, nil}
|
||||||
err := helper.SetObj("/some/key", obj)
|
err := helper.SetObj("/some/key", obj)
|
||||||
@@ -241,7 +241,7 @@ func TestAtomicUpdate(t *testing.T) {
|
|||||||
// Create a new node.
|
// Create a new node.
|
||||||
fakeClient.ExpectNotFoundGet("/some/key")
|
fakeClient.ExpectNotFoundGet("/some/key")
|
||||||
obj := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 1}
|
obj := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 1}
|
||||||
err := helper.AtomicUpdate("/some/key", &TestResource{}, func(in interface{}) (interface{}, error) {
|
err := helper.AtomicUpdate("/some/key", &TestResource{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
return obj, nil
|
return obj, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -260,7 +260,7 @@ func TestAtomicUpdate(t *testing.T) {
|
|||||||
// Update an existing node.
|
// Update an existing node.
|
||||||
callbackCalled := false
|
callbackCalled := false
|
||||||
objUpdate := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 2}
|
objUpdate := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 2}
|
||||||
err = helper.AtomicUpdate("/some/key", &TestResource{}, func(in interface{}) (interface{}, error) {
|
err = helper.AtomicUpdate("/some/key", &TestResource{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
callbackCalled = true
|
callbackCalled = true
|
||||||
|
|
||||||
if in.(*TestResource).Value != 1 {
|
if in.(*TestResource).Value != 1 {
|
||||||
@@ -295,7 +295,7 @@ func TestAtomicUpdateNoChange(t *testing.T) {
|
|||||||
// Create a new node.
|
// Create a new node.
|
||||||
fakeClient.ExpectNotFoundGet("/some/key")
|
fakeClient.ExpectNotFoundGet("/some/key")
|
||||||
obj := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 1}
|
obj := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 1}
|
||||||
err := helper.AtomicUpdate("/some/key", &TestResource{}, func(in interface{}) (interface{}, error) {
|
err := helper.AtomicUpdate("/some/key", &TestResource{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
return obj, nil
|
return obj, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -306,7 +306,7 @@ func TestAtomicUpdateNoChange(t *testing.T) {
|
|||||||
callbackCalled := false
|
callbackCalled := false
|
||||||
objUpdate := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 1}
|
objUpdate := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: 1}
|
||||||
fakeClient.Err = errors.New("should not be called")
|
fakeClient.Err = errors.New("should not be called")
|
||||||
err = helper.AtomicUpdate("/some/key", &TestResource{}, func(in interface{}) (interface{}, error) {
|
err = helper.AtomicUpdate("/some/key", &TestResource{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
callbackCalled = true
|
callbackCalled = true
|
||||||
return objUpdate, nil
|
return objUpdate, nil
|
||||||
})
|
})
|
||||||
@@ -338,7 +338,7 @@ func TestAtomicUpdate_CreateCollision(t *testing.T) {
|
|||||||
defer wgDone.Done()
|
defer wgDone.Done()
|
||||||
|
|
||||||
firstCall := true
|
firstCall := true
|
||||||
err := helper.AtomicUpdate("/some/key", &TestResource{}, func(in interface{}) (interface{}, error) {
|
err := helper.AtomicUpdate("/some/key", &TestResource{}, func(in runtime.Object) (runtime.Object, error) {
|
||||||
defer func() { firstCall = false }()
|
defer func() { firstCall = false }()
|
||||||
|
|
||||||
if firstCall {
|
if firstCall {
|
||||||
@@ -348,7 +348,7 @@ func TestAtomicUpdate_CreateCollision(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currValue := in.(*TestResource).Value
|
currValue := in.(*TestResource).Value
|
||||||
obj := TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: currValue + 1}
|
obj := &TestResource{JSONBase: api.JSONBase{ID: "foo"}, Value: currValue + 1}
|
||||||
return obj, nil
|
return obj, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package tools
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
"github.com/coreos/go-etcd/etcd"
|
"github.com/coreos/go-etcd/etcd"
|
||||||
@@ -27,10 +28,10 @@ import (
|
|||||||
|
|
||||||
// FilterFunc is a predicate which takes an API object and returns true
|
// FilterFunc is a predicate which takes an API object and returns true
|
||||||
// iff the object should remain in the set.
|
// iff the object should remain in the set.
|
||||||
type FilterFunc func(obj interface{}) bool
|
type FilterFunc func(obj runtime.Object) bool
|
||||||
|
|
||||||
// Everything is a FilterFunc which accepts all objects.
|
// Everything is a FilterFunc which accepts all objects.
|
||||||
func Everything(interface{}) bool {
|
func Everything(runtime.Object) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ func (h *EtcdHelper) Watch(key string, resourceVersion uint64) (watch.Interface,
|
|||||||
// change or wrap the serialized etcd object.
|
// change or wrap the serialized etcd object.
|
||||||
//
|
//
|
||||||
// startTime := time.Now()
|
// startTime := time.Now()
|
||||||
// helper.WatchAndTransform(key, version, func(input interface{}) (interface{}, error) {
|
// helper.WatchAndTransform(key, version, func(input runtime.Object) (runtime.Object, error) {
|
||||||
// value := input.(TimeAwareValue)
|
// value := input.(TimeAwareValue)
|
||||||
// value.Since = startTime
|
// value.Since = startTime
|
||||||
// return value, nil
|
// return value, nil
|
||||||
@@ -72,12 +73,12 @@ func (h *EtcdHelper) WatchAndTransform(key string, resourceVersion uint64, trans
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TransformFunc attempts to convert an object to another object for use with a watcher.
|
// TransformFunc attempts to convert an object to another object for use with a watcher.
|
||||||
type TransformFunc func(interface{}) (interface{}, error)
|
type TransformFunc func(runtime.Object) (runtime.Object, error)
|
||||||
|
|
||||||
// etcdWatcher converts a native etcd watch to a watch.Interface.
|
// etcdWatcher converts a native etcd watch to a watch.Interface.
|
||||||
type etcdWatcher struct {
|
type etcdWatcher struct {
|
||||||
encoding Codec
|
encoding runtime.Codec
|
||||||
versioner ResourceVersioner
|
versioner runtime.ResourceVersioner
|
||||||
transform TransformFunc
|
transform TransformFunc
|
||||||
|
|
||||||
list bool // If we're doing a recursive watch, should be true.
|
list bool // If we're doing a recursive watch, should be true.
|
||||||
@@ -98,7 +99,7 @@ type etcdWatcher struct {
|
|||||||
|
|
||||||
// newEtcdWatcher returns a new etcdWatcher; if list is true, watch sub-nodes. If you provide a transform
|
// newEtcdWatcher returns a new etcdWatcher; if list is true, watch sub-nodes. If you provide a transform
|
||||||
// and a versioner, the versioner must be able to handle the objects that transform creates.
|
// and a versioner, the versioner must be able to handle the objects that transform creates.
|
||||||
func newEtcdWatcher(list bool, filter FilterFunc, encoding Codec, versioner ResourceVersioner, transform TransformFunc) *etcdWatcher {
|
func newEtcdWatcher(list bool, filter FilterFunc, encoding runtime.Codec, versioner runtime.ResourceVersioner, transform TransformFunc) *etcdWatcher {
|
||||||
w := &etcdWatcher{
|
w := &etcdWatcher{
|
||||||
encoding: encoding,
|
encoding: encoding,
|
||||||
versioner: versioner,
|
versioner: versioner,
|
||||||
@@ -192,7 +193,7 @@ func (w *etcdWatcher) translate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *etcdWatcher) decodeObject(data []byte, index uint64) (interface{}, error) {
|
func (w *etcdWatcher) decodeObject(data []byte, index uint64) (runtime.Object, error) {
|
||||||
obj, err := w.encoding.Decode(data)
|
obj, err := w.encoding.Decode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -260,7 +261,7 @@ func (w *etcdWatcher) sendModify(res *etcd.Response) {
|
|||||||
}
|
}
|
||||||
curObjPasses := w.filter(curObj)
|
curObjPasses := w.filter(curObj)
|
||||||
oldObjPasses := false
|
oldObjPasses := false
|
||||||
var oldObj interface{}
|
var oldObj runtime.Object
|
||||||
if res.PrevNode != nil && res.PrevNode.Value != "" {
|
if res.PrevNode != nil && res.PrevNode.Value != "" {
|
||||||
// Ignore problems reading the old object.
|
// Ignore problems reading the old object.
|
||||||
if oldObj, err = w.decodeObject([]byte(res.PrevNode.Value), res.PrevNode.ModifiedIndex); err == nil {
|
if oldObj, err = w.decodeObject([]byte(res.PrevNode.Value), res.PrevNode.ModifiedIndex); err == nil {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func TestWatchInterpretations(t *testing.T) {
|
|||||||
podFoo := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
podFoo := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
podBar := &api.Pod{JSONBase: api.JSONBase{ID: "bar"}}
|
podBar := &api.Pod{JSONBase: api.JSONBase{ID: "bar"}}
|
||||||
podBaz := &api.Pod{JSONBase: api.JSONBase{ID: "baz"}}
|
podBaz := &api.Pod{JSONBase: api.JSONBase{ID: "baz"}}
|
||||||
firstLetterIsB := func(obj interface{}) bool {
|
firstLetterIsB := func(obj runtime.Object) bool {
|
||||||
return obj.(*api.Pod).ID[0] == 'b'
|
return obj.(*api.Pod).ID[0] == 'b'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,66 +44,66 @@ func TestWatchInterpretations(t *testing.T) {
|
|||||||
nodeValue string
|
nodeValue string
|
||||||
expectEmit bool
|
expectEmit bool
|
||||||
expectType watch.EventType
|
expectType watch.EventType
|
||||||
expectObject interface{}
|
expectObject runtime.Object
|
||||||
}{
|
}{
|
||||||
"create": {
|
"create": {
|
||||||
actions: []string{"create", "get"},
|
actions: []string{"create", "get"},
|
||||||
nodeValue: runtime.EncodeOrDie(podBar),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podBar),
|
||||||
expectEmit: true,
|
expectEmit: true,
|
||||||
expectType: watch.Added,
|
expectType: watch.Added,
|
||||||
expectObject: podBar,
|
expectObject: podBar,
|
||||||
},
|
},
|
||||||
"create but filter blocks": {
|
"create but filter blocks": {
|
||||||
actions: []string{"create", "get"},
|
actions: []string{"create", "get"},
|
||||||
nodeValue: runtime.EncodeOrDie(podFoo),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podFoo),
|
||||||
expectEmit: false,
|
expectEmit: false,
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
actions: []string{"delete"},
|
actions: []string{"delete"},
|
||||||
prevNodeValue: runtime.EncodeOrDie(podBar),
|
prevNodeValue: runtime.DefaultScheme.EncodeOrDie(podBar),
|
||||||
expectEmit: true,
|
expectEmit: true,
|
||||||
expectType: watch.Deleted,
|
expectType: watch.Deleted,
|
||||||
expectObject: podBar,
|
expectObject: podBar,
|
||||||
},
|
},
|
||||||
"delete but filter blocks": {
|
"delete but filter blocks": {
|
||||||
actions: []string{"delete"},
|
actions: []string{"delete"},
|
||||||
nodeValue: runtime.EncodeOrDie(podFoo),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podFoo),
|
||||||
expectEmit: false,
|
expectEmit: false,
|
||||||
},
|
},
|
||||||
"modify appears to create 1": {
|
"modify appears to create 1": {
|
||||||
actions: []string{"set", "compareAndSwap"},
|
actions: []string{"set", "compareAndSwap"},
|
||||||
nodeValue: runtime.EncodeOrDie(podBar),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podBar),
|
||||||
expectEmit: true,
|
expectEmit: true,
|
||||||
expectType: watch.Added,
|
expectType: watch.Added,
|
||||||
expectObject: podBar,
|
expectObject: podBar,
|
||||||
},
|
},
|
||||||
"modify appears to create 2": {
|
"modify appears to create 2": {
|
||||||
actions: []string{"set", "compareAndSwap"},
|
actions: []string{"set", "compareAndSwap"},
|
||||||
prevNodeValue: runtime.EncodeOrDie(podFoo),
|
prevNodeValue: runtime.DefaultScheme.EncodeOrDie(podFoo),
|
||||||
nodeValue: runtime.EncodeOrDie(podBar),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podBar),
|
||||||
expectEmit: true,
|
expectEmit: true,
|
||||||
expectType: watch.Added,
|
expectType: watch.Added,
|
||||||
expectObject: podBar,
|
expectObject: podBar,
|
||||||
},
|
},
|
||||||
"modify appears to delete": {
|
"modify appears to delete": {
|
||||||
actions: []string{"set", "compareAndSwap"},
|
actions: []string{"set", "compareAndSwap"},
|
||||||
prevNodeValue: runtime.EncodeOrDie(podBar),
|
prevNodeValue: runtime.DefaultScheme.EncodeOrDie(podBar),
|
||||||
nodeValue: runtime.EncodeOrDie(podFoo),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podFoo),
|
||||||
expectEmit: true,
|
expectEmit: true,
|
||||||
expectType: watch.Deleted,
|
expectType: watch.Deleted,
|
||||||
expectObject: podBar, // Should return last state that passed the filter!
|
expectObject: podBar, // Should return last state that passed the filter!
|
||||||
},
|
},
|
||||||
"modify modifies": {
|
"modify modifies": {
|
||||||
actions: []string{"set", "compareAndSwap"},
|
actions: []string{"set", "compareAndSwap"},
|
||||||
prevNodeValue: runtime.EncodeOrDie(podBar),
|
prevNodeValue: runtime.DefaultScheme.EncodeOrDie(podBar),
|
||||||
nodeValue: runtime.EncodeOrDie(podBaz),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podBaz),
|
||||||
expectEmit: true,
|
expectEmit: true,
|
||||||
expectType: watch.Modified,
|
expectType: watch.Modified,
|
||||||
expectObject: podBaz,
|
expectObject: podBaz,
|
||||||
},
|
},
|
||||||
"modify ignores": {
|
"modify ignores": {
|
||||||
actions: []string{"set", "compareAndSwap"},
|
actions: []string{"set", "compareAndSwap"},
|
||||||
nodeValue: runtime.EncodeOrDie(podFoo),
|
nodeValue: runtime.DefaultScheme.EncodeOrDie(podFoo),
|
||||||
expectEmit: false,
|
expectEmit: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,7 @@ func TestWatchEtcdState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Action: "create",
|
Action: "create",
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: string(runtime.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
Value: string(runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -273,12 +273,12 @@ func TestWatchEtcdState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Action: "compareAndSwap",
|
Action: "compareAndSwap",
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: string(runtime.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
Value: string(runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 2,
|
ModifiedIndex: 2,
|
||||||
},
|
},
|
||||||
PrevNode: &etcd.Node{
|
PrevNode: &etcd.Node{
|
||||||
Value: string(runtime.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
Value: string(runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 1,
|
ModifiedIndex: 1,
|
||||||
},
|
},
|
||||||
@@ -295,7 +295,7 @@ func TestWatchEtcdState(t *testing.T) {
|
|||||||
R: &etcd.Response{
|
R: &etcd.Response{
|
||||||
Action: "get",
|
Action: "get",
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: string(runtime.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
Value: string(runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 1,
|
ModifiedIndex: 1,
|
||||||
},
|
},
|
||||||
@@ -308,12 +308,12 @@ func TestWatchEtcdState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Action: "compareAndSwap",
|
Action: "compareAndSwap",
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: string(runtime.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
Value: string(runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:9000"}})),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 2,
|
ModifiedIndex: 2,
|
||||||
},
|
},
|
||||||
PrevNode: &etcd.Node{
|
PrevNode: &etcd.Node{
|
||||||
Value: string(runtime.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
Value: string(runtime.DefaultScheme.EncodeOrDie(&api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{}})),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 1,
|
ModifiedIndex: 1,
|
||||||
},
|
},
|
||||||
@@ -370,7 +370,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
|
|||||||
EtcdResponseWithError{
|
EtcdResponseWithError{
|
||||||
R: &etcd.Response{
|
R: &etcd.Response{
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: runtime.EncodeOrDie(pod),
|
Value: runtime.DefaultScheme.EncodeOrDie(pod),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 1,
|
ModifiedIndex: 1,
|
||||||
},
|
},
|
||||||
@@ -385,7 +385,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
|
|||||||
EtcdResponseWithError{
|
EtcdResponseWithError{
|
||||||
R: &etcd.Response{
|
R: &etcd.Response{
|
||||||
Node: &etcd.Node{
|
Node: &etcd.Node{
|
||||||
Value: runtime.EncodeOrDie(pod),
|
Value: runtime.DefaultScheme.EncodeOrDie(pod),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 2,
|
ModifiedIndex: 2,
|
||||||
},
|
},
|
||||||
@@ -443,13 +443,13 @@ func TestWatchListFromZeroIndex(t *testing.T) {
|
|||||||
Dir: true,
|
Dir: true,
|
||||||
Nodes: etcd.Nodes{
|
Nodes: etcd.Nodes{
|
||||||
&etcd.Node{
|
&etcd.Node{
|
||||||
Value: runtime.EncodeOrDie(pod),
|
Value: runtime.DefaultScheme.EncodeOrDie(pod),
|
||||||
CreatedIndex: 1,
|
CreatedIndex: 1,
|
||||||
ModifiedIndex: 1,
|
ModifiedIndex: 1,
|
||||||
Nodes: etcd.Nodes{},
|
Nodes: etcd.Nodes{},
|
||||||
},
|
},
|
||||||
&etcd.Node{
|
&etcd.Node{
|
||||||
Value: runtime.EncodeOrDie(pod),
|
Value: runtime.DefaultScheme.EncodeOrDie(pod),
|
||||||
CreatedIndex: 2,
|
CreatedIndex: 2,
|
||||||
ModifiedIndex: 2,
|
ModifiedIndex: 2,
|
||||||
Nodes: etcd.Nodes{},
|
Nodes: etcd.Nodes{},
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ type FilterFunc func(in Event) (out Event, keep bool)
|
|||||||
// Putting a filter on a watch, as an unavoidable side-effect due to the way
|
// Putting a filter on a watch, as an unavoidable side-effect due to the way
|
||||||
// go channels work, effectively causes the watch's event channel to have its
|
// go channels work, effectively causes the watch's event channel to have its
|
||||||
// queue length increased by one.
|
// queue length increased by one.
|
||||||
|
//
|
||||||
|
// WARNING: filter has a fatal flaw, in that it can't properly update the
|
||||||
|
// Type field (Add/Modified/Deleted) to reflect items beginning to pass the
|
||||||
|
// filter when they previously didn't.
|
||||||
|
//
|
||||||
func Filter(w Interface, f FilterFunc) Interface {
|
func Filter(w Interface, f FilterFunc) Interface {
|
||||||
fw := &filteredWatch{
|
fw := &filteredWatch{
|
||||||
incoming: w,
|
incoming: w,
|
||||||
|
|||||||
@@ -23,16 +23,16 @@ import (
|
|||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
func TestFilter(t *testing.T) {
|
||||||
table := []Event{
|
table := []Event{
|
||||||
{Added, "foo"},
|
{Added, testType("foo")},
|
||||||
{Added, "bar"},
|
{Added, testType("bar")},
|
||||||
{Added, "baz"},
|
{Added, testType("baz")},
|
||||||
{Added, "qux"},
|
{Added, testType("qux")},
|
||||||
{Added, "zoo"},
|
{Added, testType("zoo")},
|
||||||
}
|
}
|
||||||
|
|
||||||
source := NewFake()
|
source := NewFake()
|
||||||
filtered := Filter(source, func(e Event) (Event, bool) {
|
filtered := Filter(source, func(e Event) (Event, bool) {
|
||||||
return e, e.Object.(string)[0] != 'b'
|
return e, e.Object.(testType)[0] != 'b'
|
||||||
})
|
})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -48,7 +48,7 @@ func TestFilter(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
got = append(got, event.Object.(string))
|
got = append(got, string(event.Object.(testType)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if e, a := []string{"foo", "qux", "zoo"}, got; !reflect.DeepEqual(e, a) {
|
if e, a := []string{"foo", "qux", "zoo"}, got; !reflect.DeepEqual(e, a) {
|
||||||
@@ -59,11 +59,11 @@ func TestFilter(t *testing.T) {
|
|||||||
func TestFilterStop(t *testing.T) {
|
func TestFilterStop(t *testing.T) {
|
||||||
source := NewFake()
|
source := NewFake()
|
||||||
filtered := Filter(source, func(e Event) (Event, bool) {
|
filtered := Filter(source, func(e Event) (Event, bool) {
|
||||||
return e, e.Object.(string)[0] != 'b'
|
return e, e.Object.(testType)[0] != 'b'
|
||||||
})
|
})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
source.Add("foo")
|
source.Add(testType("foo"))
|
||||||
filtered.Stop()
|
filtered.Stop()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ func TestFilterStop(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
got = append(got, event.Object.(string))
|
got = append(got, string(event.Object.(testType)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if e, a := []string{"foo"}, got; !reflect.DeepEqual(e, a) {
|
if e, a := []string{"foo"}, got; !reflect.DeepEqual(e, a) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package watch
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ type Decoder interface {
|
|||||||
// Decode should return the type of event, the decoded object, or an error.
|
// Decode should return the type of event, the decoded object, or an error.
|
||||||
// An error will cause StreamWatcher to call Close(). Decode should block until
|
// An error will cause StreamWatcher to call Close(). Decode should block until
|
||||||
// it has data or an error occurs.
|
// it has data or an error occurs.
|
||||||
Decode() (action EventType, object interface{}, err error)
|
Decode() (action EventType, object runtime.Object, err error)
|
||||||
|
|
||||||
// Close should close the underlying io.Reader, signalling to the source of
|
// Close should close the underlying io.Reader, signalling to the source of
|
||||||
// the stream that it is no longer being watched. Close() must cause any
|
// the stream that it is no longer being watched. Close() must cause any
|
||||||
|
|||||||
@@ -20,13 +20,15 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeDecoder struct {
|
type fakeDecoder struct {
|
||||||
items chan Event
|
items chan Event
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f fakeDecoder) Decode() (action EventType, object interface{}, err error) {
|
func (f fakeDecoder) Decode() (action EventType, object runtime.Object, err error) {
|
||||||
item, open := <-f.items
|
item, open := <-f.items
|
||||||
if !open {
|
if !open {
|
||||||
return action, nil, io.EOF
|
return action, nil, io.EOF
|
||||||
@@ -40,7 +42,7 @@ func (f fakeDecoder) Close() {
|
|||||||
|
|
||||||
func TestStreamWatcher(t *testing.T) {
|
func TestStreamWatcher(t *testing.T) {
|
||||||
table := []Event{
|
table := []Event{
|
||||||
{Added, "foo"},
|
{Added, testType("foo")},
|
||||||
}
|
}
|
||||||
|
|
||||||
fd := fakeDecoder{make(chan Event, 5)}
|
fd := fakeDecoder{make(chan Event, 5)}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package watch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mux distributes event notifications among any number of watchers. Every event
|
// Mux distributes event notifications among any number of watchers. Every event
|
||||||
@@ -88,7 +90,7 @@ func (m *Mux) closeAll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Action distributes the given event among all watchers.
|
// Action distributes the given event among all watchers.
|
||||||
func (m *Mux) Action(action EventType, obj interface{}) {
|
func (m *Mux) Action(action EventType, obj runtime.Object) {
|
||||||
m.incoming <- Event{action, obj}
|
m.incoming <- Event{action, obj}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,16 +22,19 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type myType struct {
|
||||||
|
ID string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*myType) IsAnAPIObject() {}
|
||||||
|
|
||||||
func TestMux(t *testing.T) {
|
func TestMux(t *testing.T) {
|
||||||
type myType struct {
|
|
||||||
ID string
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
table := []Event{
|
table := []Event{
|
||||||
{Added, myType{"foo", "hello world 1"}},
|
{Added, &myType{"foo", "hello world 1"}},
|
||||||
{Added, myType{"bar", "hello world 2"}},
|
{Added, &myType{"bar", "hello world 2"}},
|
||||||
{Modified, myType{"foo", "goodbye world 3"}},
|
{Modified, &myType{"foo", "goodbye world 3"}},
|
||||||
{Deleted, myType{"bar", "hello world 4"}},
|
{Deleted, &myType{"bar", "hello world 4"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
// The mux we're testing
|
// The mux we're testing
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package watch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Interface can be implemented by anything that knows how to watch and report changes.
|
// Interface can be implemented by anything that knows how to watch and report changes.
|
||||||
@@ -47,7 +49,7 @@ type Event struct {
|
|||||||
|
|
||||||
// If Type == Deleted, then this is the state of the object
|
// If Type == Deleted, then this is the state of the object
|
||||||
// immediately before deletion.
|
// immediately before deletion.
|
||||||
Object interface{}
|
Object runtime.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
// FakeWatcher lets you test anything that consumes a watch.Interface; threadsafe.
|
// FakeWatcher lets you test anything that consumes a watch.Interface; threadsafe.
|
||||||
@@ -78,21 +80,21 @@ func (f *FakeWatcher) ResultChan() <-chan Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add sends an add event.
|
// Add sends an add event.
|
||||||
func (f *FakeWatcher) Add(obj interface{}) {
|
func (f *FakeWatcher) Add(obj runtime.Object) {
|
||||||
f.result <- Event{Added, obj}
|
f.result <- Event{Added, obj}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify sends a modify event.
|
// Modify sends a modify event.
|
||||||
func (f *FakeWatcher) Modify(obj interface{}) {
|
func (f *FakeWatcher) Modify(obj runtime.Object) {
|
||||||
f.result <- Event{Modified, obj}
|
f.result <- Event{Modified, obj}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete sends a delete event.
|
// Delete sends a delete event.
|
||||||
func (f *FakeWatcher) Delete(lastValue interface{}) {
|
func (f *FakeWatcher) Delete(lastValue runtime.Object) {
|
||||||
f.result <- Event{Deleted, lastValue}
|
f.result <- Event{Deleted, lastValue}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action sends an event of the requested type, for table-based testing.
|
// Action sends an event of the requested type, for table-based testing.
|
||||||
func (f *FakeWatcher) Action(action EventType, obj interface{}) {
|
func (f *FakeWatcher) Action(action EventType, obj runtime.Object) {
|
||||||
f.result <- Event{action, obj}
|
f.result <- Event{action, obj}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,17 +20,21 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type testType string
|
||||||
|
|
||||||
|
func (testType) IsAnAPIObject() {}
|
||||||
|
|
||||||
func TestFake(t *testing.T) {
|
func TestFake(t *testing.T) {
|
||||||
f := NewFake()
|
f := NewFake()
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
t EventType
|
t EventType
|
||||||
s string
|
s testType
|
||||||
}{
|
}{
|
||||||
{Added, "foo"},
|
{Added, testType("foo")},
|
||||||
{Modified, "qux"},
|
{Modified, testType("qux")},
|
||||||
{Modified, "bar"},
|
{Modified, testType("bar")},
|
||||||
{Deleted, "bar"},
|
{Deleted, testType("bar")},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prove that f implements Interface by phrasing this as a function.
|
// Prove that f implements Interface by phrasing this as a function.
|
||||||
@@ -43,7 +47,7 @@ func TestFake(t *testing.T) {
|
|||||||
if e, a := expect.t, got.Type; e != a {
|
if e, a := expect.t, got.Type; e != a {
|
||||||
t.Fatalf("Expected %v, got %v", e, a)
|
t.Fatalf("Expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if a, ok := got.Object.(string); !ok || a != expect.s {
|
if a, ok := got.Object.(testType); !ok || a != expect.s {
|
||||||
t.Fatalf("Expected %v, got %v", expect.s, a)
|
t.Fatalf("Expected %v, got %v", expect.s, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,10 +58,10 @@ func TestFake(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sender := func() {
|
sender := func() {
|
||||||
f.Add("foo")
|
f.Add(testType("foo"))
|
||||||
f.Action(Modified, "qux")
|
f.Action(Modified, testType("qux"))
|
||||||
f.Modify("bar")
|
f.Modify(testType("bar"))
|
||||||
f.Delete("bar")
|
f.Delete(testType("bar"))
|
||||||
f.Stop()
|
f.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func TestPollMinions(t *testing.T) {
|
|||||||
ml := &api.MinionList{Items: item.minions}
|
ml := &api.MinionList{Items: item.minions}
|
||||||
handler := util.FakeHandler{
|
handler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: runtime.EncodeOrDie(ml),
|
ResponseBody: runtime.DefaultScheme.EncodeOrDie(ml),
|
||||||
T: t,
|
T: t,
|
||||||
}
|
}
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@@ -140,7 +140,7 @@ func TestDefaultErrorFunc(t *testing.T) {
|
|||||||
testPod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
testPod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||||
handler := util.FakeHandler{
|
handler := util.FakeHandler{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
ResponseBody: runtime.EncodeOrDie(testPod),
|
ResponseBody: runtime.DefaultScheme.EncodeOrDie(testPod),
|
||||||
T: t,
|
T: t,
|
||||||
}
|
}
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@@ -259,7 +259,7 @@ func TestBind(t *testing.T) {
|
|||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
expectedBody := runtime.EncodeOrDie(item.binding)
|
expectedBody := runtime.DefaultScheme.EncodeOrDie(item.binding)
|
||||||
handler.ValidateRequest(t, "/api/v1beta1/bindings", "POST", &expectedBody)
|
handler.ValidateRequest(t, "/api/v1beta1/bindings", "POST", &expectedBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func TestClient(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get a validation error
|
// get a validation error
|
||||||
pod := api.Pod{
|
pod := &api.Pod{
|
||||||
DesiredState: api.PodState{
|
DesiredState: api.PodState{
|
||||||
Manifest: api.ContainerManifest{
|
Manifest: api.ContainerManifest{
|
||||||
Version: "v1beta2",
|
Version: "v1beta2",
|
||||||
|
|||||||
@@ -33,17 +33,22 @@ func init() {
|
|||||||
|
|
||||||
type stringCodec struct{}
|
type stringCodec struct{}
|
||||||
|
|
||||||
func (c stringCodec) Encode(obj interface{}) ([]byte, error) {
|
type fakeAPIObject string
|
||||||
return []byte(obj.(string)), nil
|
|
||||||
|
func (*fakeAPIObject) IsAnAPIObject() {}
|
||||||
|
|
||||||
|
func (c stringCodec) Encode(obj runtime.Object) ([]byte, error) {
|
||||||
|
return []byte(*obj.(*fakeAPIObject)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c stringCodec) Decode(data []byte) (interface{}, error) {
|
func (c stringCodec) Decode(data []byte) (runtime.Object, error) {
|
||||||
return string(data), nil
|
o := fakeAPIObject(data)
|
||||||
|
return &o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c stringCodec) DecodeInto(data []byte, obj interface{}) error {
|
func (c stringCodec) DecodeInto(data []byte, obj runtime.Object) error {
|
||||||
o := obj.(*string)
|
o := obj.(*fakeAPIObject)
|
||||||
*o = string(data)
|
*o = fakeAPIObject(data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +56,8 @@ func TestSetObj(t *testing.T) {
|
|||||||
client := newEtcdClient()
|
client := newEtcdClient()
|
||||||
helper := tools.EtcdHelper{Client: client, Codec: stringCodec{}}
|
helper := tools.EtcdHelper{Client: client, Codec: stringCodec{}}
|
||||||
withEtcdKey(func(key string) {
|
withEtcdKey(func(key string) {
|
||||||
if err := helper.SetObj(key, "object"); err != nil {
|
fakeObject := fakeAPIObject("object")
|
||||||
|
if err := helper.SetObj(key, &fakeObject); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
resp, err := client.Get(key, false, false)
|
resp, err := client.Get(key, false, false)
|
||||||
@@ -72,7 +78,7 @@ func TestExtractObj(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
s := ""
|
s := fakeAPIObject("")
|
||||||
if err := helper.ExtractObj(key, &s, false); err != nil {
|
if err := helper.ExtractObj(key, &s, false); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -84,9 +90,9 @@ func TestExtractObj(t *testing.T) {
|
|||||||
|
|
||||||
func TestWatch(t *testing.T) {
|
func TestWatch(t *testing.T) {
|
||||||
client := newEtcdClient()
|
client := newEtcdClient()
|
||||||
helper := tools.EtcdHelper{Client: client, Codec: runtime.Codec, ResourceVersioner: runtime.ResourceVersioner}
|
helper := tools.EtcdHelper{Client: client, Codec: runtime.DefaultCodec, ResourceVersioner: runtime.DefaultResourceVersioner}
|
||||||
withEtcdKey(func(key string) {
|
withEtcdKey(func(key string) {
|
||||||
resp, err := client.Set(key, runtime.EncodeOrDie(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
resp, err := client.Set(key, runtime.DefaultScheme.EncodeOrDie(&api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user