diff options
author | Konrad Bańka <k.banka@samsung.com> | 2021-03-09 15:57:37 +0100 |
---|---|---|
committer | Konrad Bańka <k.banka@samsung.com> | 2021-03-09 15:57:37 +0100 |
commit | b00a7930a27afed7ba2576378aeecc75fb0759f3 (patch) | |
tree | a856508c4486e937fc4287e1f0ae4fdbec03543b | |
parent | 5a382efb6d44399190c63d9d39dbc25069f74f61 (diff) |
Correct Query API endpoint registration
Apart from corrections, corrected handling of name-only query requests
as well as provided bunch of UTs.
Issue-ID: MULTICLOUD-1307
Signed-off-by: Konrad Bańka <k.banka@samsung.com>
Change-Id: Ida3d3e434525f323bd8c40ddc7ffd58df9c5e831
-rw-r--r-- | src/k8splugin/api/api.go | 2 | ||||
-rw-r--r-- | src/k8splugin/api/instancehandler_test.go | 270 | ||||
-rw-r--r-- | src/k8splugin/internal/app/instance.go | 6 |
3 files changed, 276 insertions, 2 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go index 2c53a297..4a196ae2 100644 --- a/src/k8splugin/api/api.go +++ b/src/k8splugin/api/api.go @@ -47,9 +47,9 @@ func NewRouter(defClient rb.DefinitionManager, Queries("rb-name", "{rb-name}", "rb-version", "{rb-version}", "profile-name", "{profile-name}").Methods("GET") - instRouter.HandleFunc("/instance/{instID}", instHandler.getHandler).Methods("GET") instRouter.HandleFunc("/instance/{instID}/status", instHandler.statusHandler).Methods("GET") + instRouter.HandleFunc("/instance/{instID}/query", instHandler.queryHandler).Methods("GET") instRouter.HandleFunc("/instance/{instID}/query", instHandler.queryHandler). Queries("ApiVersion", "{ApiVersion}", "Kind", "{Kind}", diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go index 8e6c72fc..e05bd2d7 100644 --- a/src/k8splugin/api/instancehandler_test.go +++ b/src/k8splugin/api/instancehandler_test.go @@ -20,10 +20,13 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + neturl "net/url" "reflect" "sort" "testing" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/app" "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm" @@ -61,6 +64,14 @@ func (m *mockInstanceClient) Get(id string) (app.InstanceResponse, error) { return m.items[0], nil } +func (m *mockInstanceClient) Query(id, apiVersion, kind, name, labels string) (app.InstanceStatus, error) { + if m.err != nil { + return app.InstanceStatus{}, m.err + } + + return m.statusItem, nil +} + func (m *mockInstanceClient) Status(id string) (app.InstanceStatus, error) { if m.err != nil { return app.InstanceStatus{}, m.err @@ -497,3 +508,262 @@ func TestDeleteHandler(t *testing.T) { }) } } + +func TestInstanceQueryHandler(t *testing.T) { + testCases := []struct { + label string + input map[string]string + id string + expectedCode int + expectedResponse *app.InstanceStatus + instClient *mockInstanceClient + }{ + { + label: "Missing apiVersion mandatory parameter", + id: "HaKpys8e", + input: map[string]string{}, + expectedCode: http.StatusBadRequest, + instClient: &mockInstanceClient{ + err: pkgerrors.New("Missing apiVersion mandatory parameter"), + }, + }, + { + label: "Missing kind mandatory parameter", + id: "HaKpys8e", + input: map[string]string{ + "ApiVersion": "v1", + }, + expectedCode: http.StatusBadRequest, + instClient: &mockInstanceClient{ + err: pkgerrors.New("Missing kind mandatory parameter"), + }, + }, + { + label: "Missing name or label mandatory parameters", + id: "HaKpys8e", + input: map[string]string{ + "ApiVersion": "v1", + "Kind": "Pod", + }, + expectedCode: http.StatusBadRequest, + instClient: &mockInstanceClient{ + err: pkgerrors.New("Name or Labels parameter must be provided"), + }, + }, + { + label: "Query instance by name", + id: "HaKpys8e", + input: map[string]string{ + "ApiVersion": "v1", + "Kind": "Pod", + "Name": "Test", + }, + expectedCode: http.StatusOK, + expectedResponse: &app.InstanceStatus{ + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Ready: false, + ResourceCount: int32(1), + ResourcesStatus: []app.ResourceStatus{ + { + Name: "Test", + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + Status: unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": map[string]interface{}{ + "name": string("Test"), + }, + }, + }, + }, + }, + }, + instClient: &mockInstanceClient{ + statusItem: app.InstanceStatus{ + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Ready: false, + ResourceCount: int32(1), + ResourcesStatus: []app.ResourceStatus{ + { + Name: "Test", + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + Status: unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": map[string]interface{}{ + "name": string("Test"), + }, + }, + }, + }, + }, + }, + }, + }, + { + label: "Query instance by label", + id: "HaKpys8e", + input: map[string]string{ + "ApiVersion": "v1", + "Kind": "Pod", + "Labels": "app=test", + }, + expectedCode: http.StatusOK, + expectedResponse: &app.InstanceStatus{ + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Ready: false, + ResourceCount: int32(1), + ResourcesStatus: []app.ResourceStatus{ + { + Name: "Test-1", + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + Status: unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": map[string]interface{}{ + "name": string("Test-1"), + "labels": map[string]interface{}{ + "app": string("test"), + }, + }, + }, + }, + }, + { + Name: "Test-2", + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + Status: unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": map[string]interface{}{ + "name": string("Test-2"), + "labels": map[string]interface{}{ + "app": string("test"), + }, + }, + }, + }, + }, + }, + }, + instClient: &mockInstanceClient{ + statusItem: app.InstanceStatus{ + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Ready: false, + ResourceCount: int32(1), + ResourcesStatus: []app.ResourceStatus{ + { + Name: "Test-1", + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + Status: unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": map[string]interface{}{ + "name": string("Test-1"), + "labels": map[string]interface{}{ + "app": string("test"), + }, + }, + }, + }, + }, + { + Name: "Test-2", + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + Status: unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": map[string]interface{}{ + "name": string("Test-2"), + "labels": map[string]interface{}{ + "app": string("test"), + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + params := neturl.Values{} + for k, v := range testCase.input { + params.Add(k, v) + } + url := "/v1/instance/" + testCase.id + "/query?" + params.Encode() + request := httptest.NewRequest("GET", url, nil) + resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil, nil, nil)) + + if testCase.expectedCode != resp.StatusCode { + body, _ := ioutil.ReadAll(resp.Body) + t.Fatalf("Request method returned: %v and it was expected: %v\nReturned body: %s", + resp.StatusCode, testCase.expectedCode, body) + } + if resp.StatusCode == http.StatusOK { + var response app.InstanceStatus + err := json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + t.Fatalf("Parsing the returned response got an error (%s)", err) + } + if !reflect.DeepEqual(testCase.expectedResponse, &response) { + t.Fatalf("TestQueryHandler returned:\n result=%v\n expected=%v", + &response, testCase.expectedResponse) + } + } + }) + } +} diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index 337ce687..b90a6428 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -22,6 +22,7 @@ import ( "log" "strings" + "k8s.io/apimachinery/pkg/runtime/schema" protorelease "k8s.io/helm/pkg/proto/hapi/release" "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" @@ -259,7 +260,10 @@ func (v *InstanceClient) Query(id, apiVersion, kind, name, labels string) (Insta resourcesStatus = resList } } else if name != "" { - resIdentifier := helm.KubernetesResource{} + resIdentifier := helm.KubernetesResource{ + Name: name, + GVK: schema.FromAPIVersionAndKind(apiVersion, kind), + } res, err := k8sClient.getResourceStatus(resIdentifier, resResp.Namespace) if err != nil { return InstanceStatus{}, pkgerrors.Wrap(err, "Querying Resource") |