From 2fc8828798695d7e07d3ed79a8fa38bdf797078a Mon Sep 17 00:00:00 2001 From: Andrej Krejcir Date: Wed, 23 Aug 2023 13:50:11 +0200 Subject: [PATCH] fix: API discovery The API discovery endpoint returns properly filled json. Signed-off-by: Andrej Krejcir --- pkg/console/console.go | 36 ++++++++++++++++++++++++++++-------- tests/api_extension_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 tests/api_extension_test.go diff --git a/pkg/console/console.go b/pkg/console/console.go index 5f08180c..7e716a03 100644 --- a/pkg/console/console.go +++ b/pkg/console/console.go @@ -88,9 +88,7 @@ func Run() error { func webService(handlers service.Service) *restful.WebService { ws := new(restful.WebService) - ws.Path("/apis/" + api.Group + "/" + api.Version) - - ws.Route(ws.GET("/namespaces/{namespace:[a-z0-9][a-z0-9\\-]*}/virtualmachines/{name:[a-z0-9][a-z0-9\\-]*}/vnc"). + ws.Route(ws.GET("/apis/" + api.Group + "/" + api.Version + "/namespaces/{namespace:[a-z0-9][a-z0-9\\-]*}/virtualmachines/{name:[a-z0-9][a-z0-9\\-]*}/vnc"). To(handlers.TokenHandler). Doc("generate token"). Operation("token"). @@ -99,17 +97,39 @@ func webService(handlers service.Service) *restful.WebService { Param(ws.QueryParameter("duration", "duration"))) // This endpoint is called by the API Server to get available resources. - // We can return an empty list here, it does not block the functionality. - ws.Route(ws.GET("/"). + ws.Route(ws.GET("/apis/"+api.Group+"/"+api.Version). To(func(request *restful.Request, response *restful.Response) { list := &metav1.APIResourceList{ TypeMeta: metav1.TypeMeta{ - Kind: "APIResourceList", + Kind: "APIResourceList", + APIVersion: metav1.SchemeGroupVersion.String(), }, - APIResources: []metav1.APIResource{}, + GroupVersion: api.Group + "/" + api.Version, + APIResources: []metav1.APIResource{{ + Name: "virtualmachines/vnc", + Namespaced: true, + Verbs: []string{"get"}, + }}, } response.WriteAsJson(list) - })) + }). + Operation("getAPIResources"). + Doc("Get API resources"). + Returns(http.StatusOK, "OK", metav1.APIResourceList{})) + + // K8s needs the ability to query the root paths + ws.Route(ws.GET("/"). + Produces(restful.MIME_JSON).Writes(metav1.RootPaths{}). + To(func(request *restful.Request, response *restful.Response) { + response.WriteAsJson(&metav1.RootPaths{ + Paths: []string{ + "/apis/" + api.Group + "/" + api.Version, + }, + }) + }). + Operation("getRootPaths"). + Doc("Get API root paths"). + Returns(http.StatusOK, "OK", metav1.RootPaths{})) return ws } diff --git a/tests/api_extension_test.go b/tests/api_extension_test.go new file mode 100644 index 00000000..cdfcfb8b --- /dev/null +++ b/tests/api_extension_test.go @@ -0,0 +1,36 @@ +package tests + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var _ = Describe("API extension", func() { + // This test case checks fix for bug: https://issues.redhat.com/browse/CNV-32267 + It("should be able to delete a namespace", func() { + testNamespace := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "test-namespace-", + }, + } + + testNamespace, err := ApiClient.CoreV1().Namespaces().Create(context.TODO(), testNamespace, metav1.CreateOptions{}) + Expect(err).ToNot(HaveOccurred()) + + Expect(ApiClient.CoreV1().Namespaces().Delete(context.TODO(), testNamespace.Name, metav1.DeleteOptions{})).To(Succeed()) + + // The namespace should be deleted + Eventually(func() metav1.StatusReason { + _, err := ApiClient.CoreV1().Namespaces().Get(context.TODO(), testNamespace.Name, metav1.GetOptions{}) + return errors.ReasonForError(err) + }, time.Minute, time.Second). + Should(Equal(metav1.StatusReasonNotFound)) + }) +})