diff options
-rw-r--r-- | src/k8splugin/internal/app/instance.go | 43 | ||||
-rw-r--r-- | src/k8splugin/internal/app/instance_test.go | 390 |
2 files changed, 433 insertions, 0 deletions
diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index 6d0910d0..41eca211 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -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) diff --git a/src/k8splugin/internal/app/instance_test.go b/src/k8splugin/internal/app/instance_test.go index 6ab14a34..2fa2115b 100644 --- a/src/k8splugin/internal/app/instance_test.go +++ b/src/k8splugin/internal/app/instance_test.go @@ -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 |