diff --git a/apis/root_handler.go b/apis/root_handler.go index b170b0d..df4f9b0 100644 --- a/apis/root_handler.go +++ b/apis/root_handler.go @@ -1,8 +1,11 @@ package apis import ( + "encoding/json" "net/http" + "code.cloudfoundry.org/cf-k8s-api/presenter" + "github.com/go-logr/logr" "github.com/gorilla/mux" ) @@ -11,16 +14,21 @@ const ( ) type RootHandler struct { + logger logr.Logger serverURL string } -func NewRootHandler(serverURL string) *RootHandler { +func NewRootHandler(logger logr.Logger, serverURL string) *RootHandler { return &RootHandler{serverURL: serverURL} } func (h *RootHandler) rootGetHandler(w http.ResponseWriter, r *http.Request) { - body := `{"links":{"self":{"href":"` + h.serverURL + `"},"bits_service":null,"cloud_controller_v2":null,"cloud_controller_v3":{"href":"` + h.serverURL + `/v3","meta":{"version":"3.90.0"}},"network_policy_v0":null,"network_policy_v1":null,"login":null,"uaa":null,"credhub":null,"routing":null,"logging":null,"log_cache":null,"log_stream":null,"app_ssh":null}}` - + body, err := json.Marshal(presenter.GetRootResponse(h.serverURL)) + if err != nil { + h.logger.Error(err, "Failed to render response") + writeUnknownErrorResponse(w) + return + } w.Header().Set("Content-Type", "application/json") w.Write([]byte(body)) } diff --git a/apis/root_handler_test.go b/apis/root_handler_test.go index 6cc2305..c750fdb 100644 --- a/apis/root_handler_test.go +++ b/apis/root_handler_test.go @@ -1,14 +1,18 @@ package apis_test import ( + "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gorilla/mux" + logf "sigs.k8s.io/controller-runtime/pkg/log" "code.cloudfoundry.org/cf-k8s-api/apis" + "code.cloudfoundry.org/cf-k8s-api/presenter" . "github.com/onsi/gomega" + "github.com/onsi/gomega/gstruct" "github.com/sclevine/spec" "github.com/sclevine/spec/report" ) @@ -29,7 +33,10 @@ func testRootAPI(t *testing.T, when spec.G, it spec.S) { rr = httptest.NewRecorder() router := mux.NewRouter() - apiHandler := apis.NewRootHandler(defaultServerURL) + apiHandler := apis.NewRootHandler( + logf.Log.WithName("TestRootHandler"), + defaultServerURL, + ) apiHandler.RegisterRoutes(router) router.ServeHTTP(rr, req) @@ -49,7 +56,32 @@ func testRootAPI(t *testing.T, when spec.G, it spec.S) { }) it("matches the expected response body format", func() { - expectedBody := `{"links":{"self":{"href":"` + defaultServerURL + `"},"bits_service":null,"cloud_controller_v2":null,"cloud_controller_v3":{"href":"` + defaultServerURL + `/v3","meta":{"version":"3.90.0"}},"network_policy_v0":null,"network_policy_v1":null,"login":null,"uaa":null,"credhub":null,"routing":null,"logging":null,"log_cache":null,"log_stream":null,"app_ssh":null}}` - g.Expect(rr.Body.String()).To(Equal(expectedBody), "Response body matches RootV3GetHandler response:") + var resp presenter.RootResponse + g.Expect(json.Unmarshal(rr.Body.Bytes(), &resp)).To(Succeed()) + + g.Expect(resp).To(gstruct.MatchAllFields(gstruct.Fields{ + "Links": Equal(map[string]*presenter.APILink{ + "self": { + Link: presenter.Link{HREF: defaultServerURL}, + }, + "bits_service": nil, + "cloud_controller_v2": nil, + "cloud_controller_v3": { + Link: presenter.Link{HREF: defaultServerURL + "/v3"}, + Meta: presenter.APILinkMeta{Version: "3.90.0"}, + }, + "network_policy_v0": nil, + "network_policy_v1": nil, + "login": nil, + "uaa": nil, + "credhub": nil, + "routing": nil, + "logging": nil, + "log_cache": nil, + "log_stream": nil, + "app_ssh": nil, + }), + "CFOnK8s": Equal(true), + })) }) } diff --git a/main.go b/main.go index f1c80eb..9e1bbb8 100644 --- a/main.go +++ b/main.go @@ -50,7 +50,10 @@ func main() { handlers := []APIHandler{ apis.NewRootV3Handler(config.ServerURL), - apis.NewRootHandler(config.ServerURL), + apis.NewRootHandler( + ctrl.Log.WithName("RootHandler"), + config.ServerURL, + ), apis.NewResourceMatchesHandler(config.ServerURL), apis.NewAppHandler( ctrl.Log.WithName("AppHandler"), diff --git a/presenter/root.go b/presenter/root.go new file mode 100644 index 0000000..a90e0d4 --- /dev/null +++ b/presenter/root.go @@ -0,0 +1,37 @@ +package presenter + +type APILink struct { + Link + Meta APILinkMeta `json:"meta"` +} + +type APILinkMeta struct { + Version string `json:"version"` +} + +type RootResponse struct { + Links map[string]*APILink `json:"links"` + CFOnK8s bool `json:"cf_on_k8s"` +} + +func GetRootResponse(serverURL string) RootResponse { + return RootResponse{ + Links: map[string]*APILink{ + "self": {Link: Link{HREF: serverURL}}, + "bits_service": nil, + "cloud_controller_v2": nil, + "cloud_controller_v3": {Link: Link{HREF: serverURL + "/v3"}, Meta: APILinkMeta{Version: "3.90.0"}}, + "network_policy_v0": nil, + "network_policy_v1": nil, + "login": nil, + "uaa": nil, + "credhub": nil, + "routing": nil, + "logging": nil, + "log_cache": nil, + "log_stream": nil, + "app_ssh": nil, + }, + CFOnK8s: true, + } +}