@@ -73,29 +73,33 @@ func NewAPIServerHandler(manager cmanager.Manager, log logr.Logger, resolver Res
7373
7474 // CRUD endpoints (global objects)
7575 ws .Route (ws .POST ("/api/v1/{resource}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Create ))
76- ws .Route (ws .GET ("/api/v1/{resource}" ).To (apiServer .apiV1List ))
76+ ws .Route (ws .GET ("/api/v1/{resource}" ).If (isList ).To (apiServer .apiV1List ))
77+ ws .Route (ws .GET ("/api/v1/{resource}" ).If (isWatch ).To (apiServer .apiV1Watch ))
7778 ws .Route (ws .GET ("/api/v1/{resource}/{name}" ).To (apiServer .apiV1Get ))
7879 ws .Route (ws .PUT ("/api/v1/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Update ))
7980 ws .Route (ws .PATCH ("/api/v1/{resource}/{name}" ).Consumes (string (types .MergePatchType ), string (types .StrategicMergePatchType )).To (apiServer .apiV1Patch ))
8081 ws .Route (ws .DELETE ("/api/v1/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf , runtime .ContentTypeJSON ).To (apiServer .apiV1Delete ))
8182
8283 ws .Route (ws .POST ("/apis/{group}/{version}/{resource}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Create ))
83- ws .Route (ws .GET ("/apis/{group}/{version}/{resource}" ).To (apiServer .apiV1List ))
84+ ws .Route (ws .GET ("/apis/{group}/{version}/{resource}" ).If (isList ).To (apiServer .apiV1List ))
85+ ws .Route (ws .GET ("/apis/{group}/{version}/{resource}" ).If (isWatch ).To (apiServer .apiV1Watch ))
8486 ws .Route (ws .GET ("/apis/{group}/{version}/{resource}/{name}" ).To (apiServer .apiV1Get ))
8587 ws .Route (ws .PUT ("/apis/{group}/{version}/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Update ))
8688 ws .Route (ws .PATCH ("/apis/{group}/{version}/{resource}/{name}" ).Consumes (string (types .MergePatchType ), string (types .StrategicMergePatchType )).To (apiServer .apiV1Patch ))
8789 ws .Route (ws .DELETE ("/apis/{group}/{version}/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf , runtime .ContentTypeJSON ).To (apiServer .apiV1Delete ))
8890
8991 // CRUD endpoints (namespaced objects)
9092 ws .Route (ws .POST ("/api/v1/namespaces/{namespace}/{resource}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Create ))
91- ws .Route (ws .GET ("/api/v1/namespaces/{namespace}/{resource}" ).To (apiServer .apiV1List ))
93+ ws .Route (ws .GET ("/api/v1/namespaces/{namespace}/{resource}" ).If (isList ).To (apiServer .apiV1List ))
94+ ws .Route (ws .GET ("/api/v1/namespaces/{namespace}/{resource}" ).If (isWatch ).To (apiServer .apiV1Watch ))
9295 ws .Route (ws .GET ("/api/v1/namespaces/{namespace}/{resource}/{name}" ).To (apiServer .apiV1Get ))
9396 ws .Route (ws .PUT ("/api/v1/namespaces/{namespace}/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Update ))
9497 ws .Route (ws .PATCH ("/api/v1/namespaces/{namespace}/{resource}/{name}" ).Consumes (string (types .MergePatchType ), string (types .StrategicMergePatchType )).To (apiServer .apiV1Patch ))
9598 ws .Route (ws .DELETE ("/api/v1/namespaces/{namespace}/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf , runtime .ContentTypeJSON ).To (apiServer .apiV1Delete ))
9699
97100 ws .Route (ws .POST ("/apis/{group}/{version}/namespaces/{namespace}/{resource}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Create ))
98- ws .Route (ws .GET ("/apis/{group}/{version}/namespaces/{namespace}/{resource}" ).To (apiServer .apiV1List ))
101+ ws .Route (ws .GET ("/apis/{group}/{version}/namespaces/{namespace}/{resource}" ).If (isList ).To (apiServer .apiV1List ))
102+ ws .Route (ws .GET ("/apis/{group}/{version}/namespaces/{namespace}/{resource}" ).If (isWatch ).To (apiServer .apiV1Watch ))
99103 ws .Route (ws .GET ("/apis/{group}/{version}/namespaces/{namespace}/{resource}/{name}" ).To (apiServer .apiV1Get ))
100104 ws .Route (ws .PUT ("/apis/{group}/{version}/namespaces/{namespace}/{resource}/{name}" ).Consumes (runtime .ContentTypeProtobuf ).To (apiServer .apiV1Update ))
101105 ws .Route (ws .PATCH ("/apis/{group}/{version}/namespaces/{namespace}/{resource}/{name}" ).Consumes (string (types .MergePatchType ), string (types .StrategicMergePatchType )).To (apiServer .apiV1Patch ))
@@ -230,16 +234,6 @@ func (h *apiServerHandler) apiV1List(req *restful.Request, resp *restful.Respons
230234 return
231235 }
232236
233- // If the request is a Watch handle it using watchForResource.
234- if isWatch (req ) {
235- err = h .watchForResource (req , resp , resourceGroup , * gvk )
236- if err != nil {
237- _ = resp .WriteErrorString (http .StatusInternalServerError , err .Error ())
238- return
239- }
240- return
241- }
242-
243237 // Reads and returns the requested data.
244238 list := & unstructured.UnstructuredList {}
245239 list .SetAPIVersion (gvk .GroupVersion ().String ())
@@ -260,6 +254,29 @@ func (h *apiServerHandler) apiV1List(req *restful.Request, resp *restful.Respons
260254 }
261255}
262256
257+ func (h * apiServerHandler ) apiV1Watch (req * restful.Request , resp * restful.Response ) {
258+ // Gets the resource group the request targets (the resolver is aware of the mapping host<->resourceGroup)
259+ resourceGroup , err := h .resourceGroupResolver (req .Request .Host )
260+ if err != nil {
261+ _ = resp .WriteErrorString (http .StatusInternalServerError , err .Error ())
262+ return
263+ }
264+
265+ // Maps the requested resource to a gvk.
266+ gvk , err := requestToGVK (req )
267+ if err != nil {
268+ _ = resp .WriteErrorString (http .StatusInternalServerError , err .Error ())
269+ return
270+ }
271+
272+ // If the request is a Watch handle it using watchForResource.
273+ err = h .watchForResource (req , resp , resourceGroup , * gvk )
274+ if err != nil {
275+ _ = resp .WriteErrorString (http .StatusInternalServerError , err .Error ())
276+ return
277+ }
278+ }
279+
263280func (h * apiServerHandler ) apiV1Get (req * restful.Request , resp * restful.Response ) {
264281 ctx := req .Request .Context ()
265282
@@ -539,3 +556,13 @@ func getAPIResourceList(req *restful.Request) *metav1.APIResourceList {
539556 }
540557 return corev1APIResourceList
541558}
559+
560+ // isWatch is true if the request contains `watch="true"` as a query parameter.
561+ func isWatch (req * http.Request ) bool {
562+ return req .URL .Query ().Get ("watch" ) == "true"
563+ }
564+
565+ // isList is true if the request does not have `watch="true` as a query parameter.
566+ func isList (req * http.Request ) bool {
567+ return ! isWatch (req )
568+ }
0 commit comments