Merge pull request #44350 from deads2k/server-17-watch

Automatic merge from submit-queue (batch tested with PRs 44868, 44350)

build external watch event so simple encoders can encode

`kube-apiserver` clients require a specific serialization of `watch.Event` to function properly.  There is no reason to allow flexibility of serialization at this point since no client would able to understand a different encoding.

I found this which trying to use a simple, unstructured json encoder and the clients kept choking on watches because it serialized without the proper json tags.

@kubernetes/sig-api-machinery-pr-reviews
This commit is contained in:
Kubernetes Submit Queue 2017-04-28 11:41:34 -07:00 committed by GitHub
commit 9fbefe3b97

View File

@ -205,9 +205,18 @@ func (s *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
unknown.Raw = buf.Bytes()
event.Object = &unknown
// the internal event will be versioned by the encoder
// create the external type directly and encode it. Clients will only recognize the serialization we provide.
// The internal event is being reused, not reallocated so its just a few extra assignments to do it this way
// and we get the benefit of using conversion functions which already have to stay in sync
outEvent := &metav1.WatchEvent{}
*internalEvent = metav1.InternalEvent(event)
if err := e.Encode(internalEvent); err != nil {
err := metav1.Convert_versioned_InternalEvent_to_versioned_Event(internalEvent, outEvent, nil)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to convert watch object: %v", err))
// client disconnect.
return
}
if err := e.Encode(outEvent); err != nil {
utilruntime.HandleError(fmt.Errorf("unable to encode watch object: %v (%#v)", err, e))
// client disconnect.
return
@ -264,8 +273,19 @@ func (s *WatchServer) HandleWS(ws *websocket.Conn) {
event.Object = &unknown
// the internal event will be versioned by the encoder
// create the external type directly and encode it. Clients will only recognize the serialization we provide.
// The internal event is being reused, not reallocated so its just a few extra assignments to do it this way
// and we get the benefit of using conversion functions which already have to stay in sync
outEvent := &metav1.WatchEvent{}
*internalEvent = metav1.InternalEvent(event)
if err := s.Encoder.Encode(internalEvent, streamBuf); err != nil {
err := metav1.Convert_versioned_InternalEvent_to_versioned_Event(internalEvent, outEvent, nil)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to convert watch object: %v", err))
// client disconnect.
s.Watching.Stop()
return
}
if err := s.Encoder.Encode(outEvent, streamBuf); err != nil {
// encoding error
utilruntime.HandleError(fmt.Errorf("unable to encode event: %v", err))
s.Watching.Stop()