// SupportedResourcesHandler returns a handler which will list the provided resources as available. func SupportedResourcesHandler(s runtime.NegotiatedSerializer, groupVersion schema.GroupVersion, lister APIResourceLister) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { responsewriters.WriteObjectNegotiated(s, schema.GroupVersion{}, resp.ResponseWriter, req.Request, http.StatusOK, &metav1.APIResourceList{GroupVersion: groupVersion.String(), APIResources: lister.ListAPIResources()}) } }
// RootAPIHandler returns a handler which will list the provided groups and versions as available. func RootAPIHandler(s runtime.NegotiatedSerializer, f func(req *restful.Request) []metav1.APIGroup) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { responsewriters.WriteObjectNegotiated(s, schema.GroupVersion{}, resp.ResponseWriter, req.Request, http.StatusOK, &metav1.APIGroupList{Groups: filterAPIGroups(req, f(req))}) } }
// GroupHandler returns a handler which will return the api.GroupAndVersion of // the group. func GroupHandler(s runtime.NegotiatedSerializer, group metav1.APIGroup) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { responsewriters.WriteObjectNegotiated(s, schema.GroupVersion{}, resp.ResponseWriter, req.Request, http.StatusOK, &group) } }
// DeleteCollection returns a function that will handle a collection deletion func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestScope, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter // TODO: we either want to remove timeout or document it (if we document, move timeout out of this function and declare it in api_installer) timeout := parseTimeout(req.Request.URL.Query().Get("timeout")) namespace, err := scope.Namer.Namespace(req) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } ctx := scope.ContextFunc(req) ctx = api.WithNamespace(ctx, namespace) if admit != nil && admit.Handles(admission.Delete) { userInfo, _ := api.UserFrom(ctx) err = admit.Admit(admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, "", scope.Resource, scope.Subresource, admission.Delete, userInfo)) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } } listOptions := api.ListOptions{} if err := scope.ParameterCodec.DecodeParameters(req.Request.URL.Query(), scope.Kind.GroupVersion(), &listOptions); err != nil { scope.err(err, res.ResponseWriter, req.Request) return } // transform fields // TODO: DecodeParametersInto should do this. if listOptions.FieldSelector != nil { fn := func(label, value string) (newLabel, newValue string, err error) { return scope.Convertor.ConvertFieldLabel(scope.Kind.GroupVersion().String(), scope.Kind.Kind, label, value) } if listOptions.FieldSelector, err = listOptions.FieldSelector.Transform(fn); err != nil { // TODO: allow bad request to set field causes based on query parameters err = errors.NewBadRequest(err.Error()) scope.err(err, res.ResponseWriter, req.Request) return } } options := &api.DeleteOptions{} if checkBody { body, err := readBody(req.Request) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } if len(body) > 0 { s, err := negotiation.NegotiateInputSerializer(req.Request, scope.Serializer) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } defaultGVK := scope.Kind.GroupVersion().WithKind("DeleteOptions") obj, _, err := scope.Serializer.DecoderToVersion(s.Serializer, defaultGVK.GroupVersion()).Decode(body, &defaultGVK, options) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } if obj != options { scope.err(fmt.Errorf("decoded object cannot be converted to DeleteOptions"), res.ResponseWriter, req.Request) return } } } result, err := finishRequest(timeout, func() (runtime.Object, error) { return r.DeleteCollection(ctx, options, &listOptions) }) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } // if the rest.Deleter returns a nil object, fill out a status. Callers may return a valid // object with the response. if result == nil { result = &metav1.Status{ Status: metav1.StatusSuccess, Code: http.StatusOK, Details: &metav1.StatusDetails{ Kind: scope.Kind.Kind, }, } } else { // when a non-status response is returned, set the self link if _, ok := result.(*metav1.Status); !ok { if _, err := setListSelfLink(result, req, scope.Namer); err != nil { scope.err(err, res.ResponseWriter, req.Request) return } } } responsewriters.WriteObjectNegotiated(scope.Serializer, scope.Kind.GroupVersion(), w, req.Request, http.StatusOK, result) } }