Add find method in instance 19/87819/1
authorKiran Kamineni <kiran.k.kamineni@intel.com>
Wed, 15 May 2019 22:22:31 +0000 (15:22 -0700)
committerKiran Kamineni <kiran.k.kamineni@intel.com>
Wed, 15 May 2019 22:22:34 +0000 (15:22 -0700)
Add a find method to get instances
based on rbname, version and profile.
If only rbname is provided, all instances based on
that resource bundle are returned.
If only rbname and version are provided, all instances
based on that combination are returned.
When all three parameters are provided, a single instance
that matches them is returned.

Issue-ID: MULTICLOUD-613
Change-Id: If63e844c77829211b807ce6cd7c11dad247751fc
Signed-off-by: Kiran Kamineni <kiran.k.kamineni@intel.com>
src/k8splugin/internal/app/instance.go
src/k8splugin/internal/app/instance_test.go

index 6d0910d..41eca21 100644 (file)
@@ -53,6 +53,7 @@ type InstanceResponse struct {
 type InstanceManager interface {
        Create(i InstanceRequest) (InstanceResponse, error)
        Get(id string) (InstanceResponse, error)
+       Find(rbName string, ver string, profile string) ([]InstanceResponse, error)
        Delete(id string) error
 }
 
@@ -176,6 +177,48 @@ func (v *InstanceClient) Get(id string) (InstanceResponse, error) {
        return InstanceResponse{}, pkgerrors.New("Error getting Instance")
 }
 
+// Find returns the instances that match the given criteria
+// If version is empty, it will return all instances for a given rbName
+// If profile is empty, it will return all instances for a given rbName+version
+func (v *InstanceClient) Find(rbName string, version string, profile string) ([]InstanceResponse, error) {
+       if rbName == "" {
+               return []InstanceResponse{}, pkgerrors.New("rbName is required and cannot be empty")
+       }
+
+       values, err := db.DBconn.ReadAll(v.storeName, v.tagInst)
+       if err != nil || len(values) == 0 {
+               return []InstanceResponse{}, pkgerrors.Wrap(err, "Find Instance")
+       }
+
+       response := []InstanceResponse{}
+       //values is a map[string][]byte
+       for _, value := range values {
+               resp := InstanceResponse{}
+               db.DBconn.Unmarshal(value, &resp)
+               if err != nil {
+                       return []InstanceResponse{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value")
+               }
+
+               if resp.RBName == rbName {
+
+                       //Check if a version is provided and if it matches
+                       if version != "" {
+                               if resp.RBVersion == version {
+                                       //Check if a profilename matches or if it is not provided
+                                       if profile == "" || resp.ProfileName == profile {
+                                               response = append(response, resp)
+                                       }
+                               }
+                       } else {
+                               //Append all versions as version is not provided
+                               response = append(response, resp)
+                       }
+               }
+       }
+
+       return response, nil
+}
+
 // Delete the Instance from database
 func (v *InstanceClient) Delete(id string) error {
        inst, err := v.Get(id)
index 6ab14a3..2fa2115 100644 (file)
@@ -18,6 +18,7 @@ import (
        "io/ioutil"
        "log"
        "reflect"
+       "sort"
        "testing"
 
        utils "k8splugin/internal"
@@ -312,6 +313,395 @@ func TestInstanceGet(t *testing.T) {
        })
 }
 
+func TestInstanceFind(t *testing.T) {
+       oldkrdPluginData := utils.LoadedPlugins
+
+       defer func() {
+               utils.LoadedPlugins = oldkrdPluginData
+       }()
+
+       err := LoadMockPlugins(utils.LoadedPlugins)
+       if err != nil {
+               t.Fatalf("LoadMockPlugins returned an error (%s)", err)
+       }
+
+       items := map[string]map[string][]byte{
+               InstanceKey{ID: "HaKpys8e"}.String(): {
+                       "instance": []byte(
+                               `{
+                                       "profile-name":"profile1",
+                                         "id":"HaKpys8e",
+                                       "namespace":"testnamespace",
+                                       "rb-name":"test-rbdef",
+                                       "rb-version":"v1",
+                                       "cloud-region":"region1",
+                                       "resources": [
+                                               {
+                                                       "GVK": {
+                                                               "Group":"apps",
+                                                               "Version":"v1",
+                                                               "Kind":"Deployment"
+                                                       },
+                                                       "Name": "deployment-1"
+                                               },
+                                               {
+                                                       "GVK": {
+                                                               "Group":"",
+                                                               "Version":"v1",
+                                                               "Kind":"Service"
+                                                       },
+                                                       "Name": "service-1"
+                                               }
+                                       ]
+                               }`),
+               },
+               InstanceKey{ID: "HaKpys8f"}.String(): {
+                       "instance": []byte(
+                               `{
+                                       "profile-name":"profile2",
+                                         "id":"HaKpys8f",
+                                       "namespace":"testnamespace",
+                                       "rb-name":"test-rbdef",
+                                       "rb-version":"v1",
+                                       "cloud-region":"region1",
+                                       "resources": [
+                                               {
+                                                       "GVK": {
+                                                               "Group":"apps",
+                                                               "Version":"v1",
+                                                               "Kind":"Deployment"
+                                                       },
+                                                       "Name": "deployment-1"
+                                               },
+                                               {
+                                                       "GVK": {
+                                                               "Group":"",
+                                                               "Version":"v1",
+                                                               "Kind":"Service"
+                                                       },
+                                                       "Name": "service-1"
+                                               }
+                                       ]
+                               }`),
+               },
+               InstanceKey{ID: "HaKpys8g"}.String(): {
+                       "instance": []byte(
+                               `{
+                                       "profile-name":"profile1",
+                                         "id":"HaKpys8g",
+                                       "namespace":"testnamespace",
+                                       "rb-name":"test-rbdef",
+                                       "rb-version":"v2",
+                                       "cloud-region":"region1",
+                                       "resources": [
+                                               {
+                                                       "GVK": {
+                                                               "Group":"apps",
+                                                               "Version":"v1",
+                                                               "Kind":"Deployment"
+                                                       },
+                                                       "Name": "deployment-1"
+                                               },
+                                               {
+                                                       "GVK": {
+                                                               "Group":"",
+                                                               "Version":"v1",
+                                                               "Kind":"Service"
+                                                       },
+                                                       "Name": "service-1"
+                                               }
+                                       ]
+                               }`),
+               },
+       }
+
+       t.Run("Successfully Find Instance By Name", func(t *testing.T) {
+               db.DBconn = &db.MockDB{
+                       Items: items,
+               }
+
+               expected := []InstanceResponse{
+                       {
+                               ID:          "HaKpys8e",
+                               RBName:      "test-rbdef",
+                               RBVersion:   "v1",
+                               ProfileName: "profile1",
+                               CloudRegion: "region1",
+                               Namespace:   "testnamespace",
+
+                               Resources: []helm.KubernetesResource{
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "apps",
+                                                       Version: "v1",
+                                                       Kind:    "Deployment"},
+                                               Name: "deployment-1",
+                                       },
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "",
+                                                       Version: "v1",
+                                                       Kind:    "Service"},
+                                               Name: "service-1",
+                                       },
+                               },
+                       },
+                       {
+                               ID:          "HaKpys8f",
+                               RBName:      "test-rbdef",
+                               RBVersion:   "v1",
+                               ProfileName: "profile2",
+                               CloudRegion: "region1",
+                               Namespace:   "testnamespace",
+
+                               Resources: []helm.KubernetesResource{
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "apps",
+                                                       Version: "v1",
+                                                       Kind:    "Deployment"},
+                                               Name: "deployment-1",
+                                       },
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "",
+                                                       Version: "v1",
+                                                       Kind:    "Service"},
+                                               Name: "service-1",
+                                       },
+                               },
+                       },
+                       {
+                               ID:          "HaKpys8g",
+                               RBName:      "test-rbdef",
+                               RBVersion:   "v2",
+                               ProfileName: "profile1",
+                               CloudRegion: "region1",
+                               Namespace:   "testnamespace",
+
+                               Resources: []helm.KubernetesResource{
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "apps",
+                                                       Version: "v1",
+                                                       Kind:    "Deployment"},
+                                               Name: "deployment-1",
+                                       },
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "",
+                                                       Version: "v1",
+                                                       Kind:    "Service"},
+                                               Name: "service-1",
+                                       },
+                               },
+                       },
+               }
+               ic := NewInstanceClient()
+               name := "test-rbdef"
+               data, err := ic.Find(name, "", "")
+               if err != nil {
+                       t.Fatalf("TestInstanceFind returned an error (%s)", err)
+               }
+
+               // Since the order of returned slice is not guaranteed
+               // Check both and return error if both don't match
+               sort.Slice(data, func(i, j int) bool {
+                       return data[i].ID < data[j].ID
+               })
+               // Sort both as it is not expected that testCase.expected
+               // is sorted
+               sort.Slice(expected, func(i, j int) bool {
+                       return expected[i].ID < expected[j].ID
+               })
+
+               if !reflect.DeepEqual(expected, data) {
+                       t.Fatalf("TestInstanceFind returned:\n result=%v\n expected=%v",
+                               data, expected)
+               }
+       })
+
+       t.Run("Successfully Find Instance By Name Version", func(t *testing.T) {
+               db.DBconn = &db.MockDB{
+                       Items: items,
+               }
+
+               expected := []InstanceResponse{
+                       {
+                               ID:          "HaKpys8e",
+                               RBName:      "test-rbdef",
+                               RBVersion:   "v1",
+                               ProfileName: "profile1",
+                               CloudRegion: "region1",
+                               Namespace:   "testnamespace",
+
+                               Resources: []helm.KubernetesResource{
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "apps",
+                                                       Version: "v1",
+                                                       Kind:    "Deployment"},
+                                               Name: "deployment-1",
+                                       },
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "",
+                                                       Version: "v1",
+                                                       Kind:    "Service"},
+                                               Name: "service-1",
+                                       },
+                               },
+                       },
+                       {
+                               ID:          "HaKpys8f",
+                               RBName:      "test-rbdef",
+                               RBVersion:   "v1",
+                               ProfileName: "profile2",
+                               CloudRegion: "region1",
+                               Namespace:   "testnamespace",
+
+                               Resources: []helm.KubernetesResource{
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "apps",
+                                                       Version: "v1",
+                                                       Kind:    "Deployment"},
+                                               Name: "deployment-1",
+                                       },
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "",
+                                                       Version: "v1",
+                                                       Kind:    "Service"},
+                                               Name: "service-1",
+                                       },
+                               },
+                       },
+               }
+               ic := NewInstanceClient()
+               name := "test-rbdef"
+               data, err := ic.Find(name, "v1", "")
+               if err != nil {
+                       t.Fatalf("TestInstanceFind returned an error (%s)", err)
+               }
+
+               // Since the order of returned slice is not guaranteed
+               // Check both and return error if both don't match
+               sort.Slice(data, func(i, j int) bool {
+                       return data[i].ID < data[j].ID
+               })
+               // Sort both as it is not expected that testCase.expected
+               // is sorted
+               sort.Slice(expected, func(i, j int) bool {
+                       return expected[i].ID < expected[j].ID
+               })
+
+               if !reflect.DeepEqual(expected, data) {
+                       t.Fatalf("TestInstanceFind returned:\n result=%v\n expected=%v",
+                               data, expected)
+               }
+       })
+
+       t.Run("Successfully Find Instance By Name Version Profile", func(t *testing.T) {
+               db.DBconn = &db.MockDB{
+                       Items: items,
+               }
+
+               expected := []InstanceResponse{
+                       {
+                               ID:          "HaKpys8e",
+                               RBName:      "test-rbdef",
+                               RBVersion:   "v1",
+                               ProfileName: "profile1",
+                               CloudRegion: "region1",
+                               Namespace:   "testnamespace",
+
+                               Resources: []helm.KubernetesResource{
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "apps",
+                                                       Version: "v1",
+                                                       Kind:    "Deployment"},
+                                               Name: "deployment-1",
+                                       },
+                                       {
+                                               GVK: schema.GroupVersionKind{
+                                                       Group:   "",
+                                                       Version: "v1",
+                                                       Kind:    "Service"},
+                                               Name: "service-1",
+                                       },
+                               },
+                       },
+               }
+               ic := NewInstanceClient()
+               name := "test-rbdef"
+               data, err := ic.Find(name, "v1", "profile1")
+               if err != nil {
+                       t.Fatalf("TestInstanceFind returned an error (%s)", err)
+               }
+
+               // Since the order of returned slice is not guaranteed
+               // Check both and return error if both don't match
+               sort.Slice(data, func(i, j int) bool {
+                       return data[i].ID < data[j].ID
+               })
+               // Sort both as it is not expected that testCase.expected
+               // is sorted
+               sort.Slice(expected, func(i, j int) bool {
+                       return expected[i].ID < expected[j].ID
+               })
+
+               if !reflect.DeepEqual(expected, data) {
+                       t.Fatalf("TestInstanceFind returned:\n result=%v\n expected=%v",
+                               data, expected)
+               }
+       })
+
+       t.Run("Find non-existing Instance", func(t *testing.T) {
+               db.DBconn = &db.MockDB{
+                       Items: map[string]map[string][]byte{
+                               InstanceKey{ID: "HaKpys8e"}.String(): {
+                                       "instance": []byte(
+                                               `{
+                                                       "profile-name":"profile1",
+                                                       "id":"HaKpys8e",
+                                                       "namespace":"testnamespace",
+                                                       "rb-name":"test-rbdef",
+                                                       "rb-version":"v1",
+                                                       "cloud-region":"region1",
+                                                       "resources": [
+                                                               {
+                                                                       "GVK": {
+                                                                               "Group":"apps",
+                                                                               "Version":"v1",
+                                                                               "Kind":"Deployment"
+                                                                       },
+                                                                       "Name": "deployment-1"
+                                                               },
+                                                               {
+                                                                       "GVK": {
+                                                                               "Group":"",
+                                                                               "Version":"v1",
+                                                                               "Kind":"Service"
+                                                                       },
+                                                                       "Name": "service-1"
+                                                               }
+                                                       ]
+                                               }`),
+                               },
+                       },
+               }
+
+               ic := NewInstanceClient()
+               name := "non-existing"
+               resp, _ := ic.Find(name, "", "")
+               if len(resp) != 0 {
+                       t.Fatalf("Expected 0 responses, but got %d", len(resp))
+               }
+       })
+}
+
 func TestInstanceDelete(t *testing.T) {
        oldkrdPluginData := utils.LoadedPlugins