diff options
author | Bin Yang <bin.yang@windriver.com> | 2019-05-24 04:37:20 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-05-24 04:37:20 +0000 |
commit | 574eb961e8651ba4e4f0f92d7984a2716e5e64f7 (patch) | |
tree | e143f2d36b1eed39100c9eb26f8b4f61e545e5da /src/k8splugin | |
parent | 3eeb40cfe56366ca72e811bdfb6f2faf127f8a2f (diff) | |
parent | 5207bd099a84832a5d7c3333bf540fa8481ce78a (diff) |
Merge changes from topics "broker_response", "develop"
* changes:
Update broker responses to match spec and SO
Minor change to instance response
Diffstat (limited to 'src/k8splugin')
-rw-r--r-- | src/k8splugin/api/api.go | 1 | ||||
-rw-r--r-- | src/k8splugin/api/brokerhandler.go | 100 | ||||
-rw-r--r-- | src/k8splugin/api/brokerhandler_test.go | 175 | ||||
-rw-r--r-- | src/k8splugin/api/instancehandler_test.go | 64 | ||||
-rw-r--r-- | src/k8splugin/internal/app/config_backend.go | 6 | ||||
-rw-r--r-- | src/k8splugin/internal/app/instance.go | 81 | ||||
-rw-r--r-- | src/k8splugin/internal/app/instance_test.go | 194 |
7 files changed, 450 insertions, 171 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go index 58e50a16..808d6f5b 100644 --- a/src/k8splugin/api/api.go +++ b/src/k8splugin/api/api.go @@ -47,6 +47,7 @@ func NewRouter(defClient rb.DefinitionManager, brokerHandler := brokerInstanceHandler{client: instClient} router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload", brokerHandler.createHandler).Methods("POST") router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload/{instID}", brokerHandler.getHandler).Methods("GET") + router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload", brokerHandler.findHandler).Queries("name", "{name}").Methods("GET") router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload/{instID}", brokerHandler.deleteHandler).Methods("DELETE") //Setup the connectivity api handler here diff --git a/src/k8splugin/api/brokerhandler.go b/src/k8splugin/api/brokerhandler.go index dca64788..c0564ee4 100644 --- a/src/k8splugin/api/brokerhandler.go +++ b/src/k8splugin/api/brokerhandler.go @@ -39,22 +39,32 @@ type brokerRequest struct { VFModuleModelVersionID string `json:"vf-module-model-version-id"` VFModuleModelCustomizationID string `json:"vf-module-model-customization-id"` OOFDirectives map[string]interface{} `json:"oof_directives"` - SDNCDirections map[string]interface{} `json:"sdnc_directives"` + SDNCDirectives map[string]interface{} `json:"sdnc_directives"` UserDirectives map[string]interface{} `json:"user_directives"` TemplateType string `json:"template_type"` TemplateData map[string]interface{} `json:"template_data"` } type brokerPOSTResponse struct { - TemplateType string `json:"template_type"` - WorkloadID string `json:"workload_id"` - TemplateResponse []helm.KubernetesResource `json:"template_response"` + TemplateType string `json:"template_type"` + WorkloadID string `json:"workload_id"` + TemplateResponse []helm.KubernetesResource `json:"template_response"` + WorkloadStatus string `json:"workload_status"` + WorkloadStatusReason map[string]interface{} `json:"workload_status_reason"` } type brokerGETResponse struct { - TemplateType string `json:"template_type"` - WorkloadID string `json:"workload_id"` - WorkloadStatus string `json:"workload_status"` + TemplateType string `json:"template_type"` + WorkloadID string `json:"workload_id"` + WorkloadStatus string `json:"workload_status"` + WorkloadStatusReason map[string]interface{} `json:"workload_status_reason"` +} + +type brokerDELETEResponse struct { + TemplateType string `json:"template_type"` + WorkloadID string `json:"workload_id"` + WorkloadStatus string `json:"workload_status"` + WorkloadStatusReason map[string]interface{} `json:"workload_status_reason"` } // getUserDirectiveValue parses the following kind of json @@ -70,8 +80,8 @@ type brokerGETResponse struct { // } // ] // } -func (b brokerRequest) getUserDirectiveValue(inp string) string { - attributes, ok := b.UserDirectives["attributes"].([]interface{}) +func (b brokerRequest) getAttributeValue(directives map[string]interface{}, inp string) string { + attributes, ok := directives["attributes"].([]interface{}) if !ok { log.Println("Unable to cast attributes to []interface{}") return "" @@ -85,12 +95,12 @@ func (b brokerRequest) getUserDirectiveValue(inp string) string { return "" } - attributename, ok := attribute["attribute_name"].(string) + attributeName, ok := attribute["attribute_name"].(string) if !ok { log.Println("Unable to cast attribute_name to string") return "" } - if attributename == inp { + if attributeName == inp { attributevalue, ok := attribute["attribute_value"].(string) if !ok { log.Println("Unable to cast attribute_value to string") @@ -124,30 +134,39 @@ func (b brokerInstanceHandler) createHandler(w http.ResponseWriter, r *http.Requ return } - rbName := req.getUserDirectiveValue("definition-name") + rbName := req.getAttributeValue(req.UserDirectives, "definition-name") if rbName == "" { http.Error(w, "definition-name is missing from user-directives", http.StatusBadRequest) return } - rbVersion := req.getUserDirectiveValue("definition-version") + rbVersion := req.getAttributeValue(req.UserDirectives, "definition-version") if rbVersion == "" { http.Error(w, "definition-version is missing from user-directives", http.StatusBadRequest) return } - profileName := req.getUserDirectiveValue("profile-name") + profileName := req.getAttributeValue(req.UserDirectives, "profile-name") if profileName == "" { http.Error(w, "profile-name is missing from user-directives", http.StatusBadRequest) return } + vfModuleName := req.getAttributeValue(req.SDNCDirectives, "vf_module_name") + if vfModuleName == "" { + http.Error(w, "vf_module_name is missing from sdnc-directives", http.StatusBadRequest) + return + } + // Setup the resource parameters for making the request var instReq app.InstanceRequest instReq.RBName = rbName instReq.RBVersion = rbVersion instReq.ProfileName = profileName instReq.CloudRegion = cloudRegion + instReq.Labels = map[string]string{ + "vf_module_name": vfModuleName, + } resp, err := b.client.Create(instReq) if err != nil { @@ -159,6 +178,7 @@ func (b brokerInstanceHandler) createHandler(w http.ResponseWriter, r *http.Requ TemplateType: "heat", WorkloadID: resp.ID, TemplateResponse: resp.Resources, + WorkloadStatus: "CREATE_COMPLETE", } w.Header().Set("Content-Type", "application/json") @@ -184,7 +204,7 @@ func (b brokerInstanceHandler) getHandler(w http.ResponseWriter, r *http.Request brokerResp := brokerGETResponse{ TemplateType: "heat", WorkloadID: resp.ID, - WorkloadStatus: "CREATED", + WorkloadStatus: "CREATE_COMPLETE", } w.Header().Set("Content-Type", "application/json") @@ -196,6 +216,45 @@ func (b brokerInstanceHandler) getHandler(w http.ResponseWriter, r *http.Request } } +// getHandler retrieves information about an instance via the ID +func (b brokerInstanceHandler) findHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + //name is an alias for vf_module_name from the so adapter + name := vars["name"] + responses, _ := b.client.Find("", "", "", map[string]string{"vf_module_name": name}) + + brokerResp := brokerGETResponse{ + TemplateType: "heat", + WorkloadID: "", + WorkloadStatus: "GET_COMPLETE", + WorkloadStatusReason: map[string]interface{}{ + //treating stacks as an array of map[string]interface{} types + "stacks": []map[string]interface{}{}, + }, + } + + if len(responses) != 0 { + //Return the first object that matches. + resp := responses[0] + brokerResp.WorkloadID = resp.ID + brokerResp.WorkloadStatus = "CREATE_COMPLETE" + brokerResp.WorkloadStatusReason["stacks"] = []map[string]interface{}{ + { + "stack_status": "CREATE_COMPLETE", + "id": resp.ID, + }, + } + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + err := json.NewEncoder(w).Encode(brokerResp) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + // deleteHandler method terminates an instance via the ID func (b brokerInstanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -207,6 +266,17 @@ func (b brokerInstanceHandler) deleteHandler(w http.ResponseWriter, r *http.Requ return } + brokerResp := brokerDELETEResponse{ + TemplateType: "heat", + WorkloadID: instanceID, + WorkloadStatus: "DELETE_COMPLETE", + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) + err = json.NewEncoder(w).Encode(brokerResp) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } } diff --git a/src/k8splugin/api/brokerhandler_test.go b/src/k8splugin/api/brokerhandler_test.go index e7ff08c4..15b7bd73 100644 --- a/src/k8splugin/api/brokerhandler_test.go +++ b/src/k8splugin/api/brokerhandler_test.go @@ -70,6 +70,14 @@ func TestBrokerCreateHandler(t *testing.T) { label: "Succesfully create an Instance", input: bytes.NewBuffer([]byte(`{ "vf-module-model-customization-id": "84sdfkio938", + "sdnc_directives": { + "attributes": [ + { + "attribute_name": "vf_module_name", + "attribute_value": "test-vf-module-name" + } + ] + }, "user_directives": { "attributes": [ { @@ -88,8 +96,9 @@ func TestBrokerCreateHandler(t *testing.T) { } }`)), expected: brokerPOSTResponse{ - WorkloadID: "HaKpys8e", - TemplateType: "heat", + WorkloadID: "HaKpys8e", + TemplateType: "heat", + WorkloadStatus: "CREATE_COMPLETE", TemplateResponse: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -111,12 +120,14 @@ func TestBrokerCreateHandler(t *testing.T) { instClient: &mockInstanceClient{ items: []app.InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -189,17 +200,19 @@ func TestBrokerGetHandler(t *testing.T) { expectedResponse: brokerGETResponse{ TemplateType: "heat", WorkloadID: "HaKpys8e", - WorkloadStatus: "CREATED", + WorkloadStatus: "CREATE_COMPLETE", }, instClient: &mockInstanceClient{ items: []app.InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -246,12 +259,118 @@ func TestBrokerGetHandler(t *testing.T) { } } +func TestBrokerFindHandler(t *testing.T) { + testCases := []struct { + label string + input string + expectedCode int + expectedResponse brokerGETResponse + instClient *mockInstanceClient + }{ + { + label: "Successful find an Instance", + input: "test-vf-module-name", + expectedCode: http.StatusOK, + expectedResponse: brokerGETResponse{ + TemplateType: "heat", + WorkloadID: "HaKpys8e", + WorkloadStatus: "CREATE_COMPLETE", + WorkloadStatusReason: map[string]interface{}{ + "stacks": []map[string]interface{}{ + { + "stack_status": "CREATE_COMPLETE", + "id": "HaKpys8e", + }, + }, + }, + }, + instClient: &mockInstanceClient{ + items: []app.InstanceResponse{ + { + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", + Resources: []helm.KubernetesResource{ + { + GVK: schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment"}, + Name: "test-deployment", + }, + { + GVK: schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service"}, + Name: "test-service", + }, + }, + }, + }, + }, + }, + { + label: "Fail to find an Instance", + input: "test-vf-module-name-1", + expectedCode: http.StatusOK, + expectedResponse: brokerGETResponse{ + TemplateType: "heat", + WorkloadID: "", + WorkloadStatus: "GET_COMPLETE", + WorkloadStatusReason: map[string]interface{}{ + "stacks": []map[string]interface{}{}, + }, + }, + instClient: &mockInstanceClient{}, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + request := httptest.NewRequest("GET", "/cloudowner/cloudregion/infra_workload?name="+testCase.input, nil) + resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil)) + + if testCase.expectedCode != resp.StatusCode { + t.Fatalf("Request method returned: %v and it was expected: %v", + resp.StatusCode, testCase.expectedCode) + } + if resp.StatusCode == http.StatusOK { + var response brokerGETResponse + err := json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + t.Fatalf("Parsing the returned response got an error (%s)", err) + } + if testCase.expectedResponse.WorkloadID != response.WorkloadID { + t.Fatalf("TestGetHandler returned:\n result=%v\n expected=%v", + response.WorkloadID, testCase.expectedResponse.WorkloadID) + } + tcStacks := testCase.expectedResponse.WorkloadStatusReason["stacks"].([]map[string]interface{}) + if len(tcStacks) != 0 { + //We expect only one response in this testcase. + resStacks := response.WorkloadStatusReason["stacks"].([]interface{})[0].(map[string]interface{}) + if !reflect.DeepEqual(tcStacks[0], resStacks) { + t.Fatalf("TestGetHandler returned:\n result=%v\n expected=%v", + resStacks, tcStacks) + } + } + } + }) + } +} + func TestBrokerDeleteHandler(t *testing.T) { testCases := []struct { - label string - input string - expectedCode int - instClient *mockInstanceClient + label string + input string + expectedCode int + expectedResponse brokerDELETEResponse + instClient *mockInstanceClient }{ { label: "Fail to destroy VNF", @@ -265,7 +384,12 @@ func TestBrokerDeleteHandler(t *testing.T) { label: "Succesful delete a VNF", input: "HaKpys8e", expectedCode: http.StatusAccepted, - instClient: &mockInstanceClient{}, + expectedResponse: brokerDELETEResponse{ + TemplateType: "heat", + WorkloadID: "HaKpys8e", + WorkloadStatus: "DELETE_COMPLETE", + }, + instClient: &mockInstanceClient{}, }, } @@ -277,6 +401,17 @@ func TestBrokerDeleteHandler(t *testing.T) { if testCase.expectedCode != resp.StatusCode { t.Fatalf("Request method returned: %v and it was expected: %v", resp.StatusCode, testCase.expectedCode) } + if resp.StatusCode == http.StatusOK { + var response brokerGETResponse + 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("TestGetHandler returned:\n result=%v\n expected=%v", + response, testCase.expectedResponse) + } + } }) } } diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go index 6d2abf6f..dac7db00 100644 --- a/src/k8splugin/api/instancehandler_test.go +++ b/src/k8splugin/api/instancehandler_test.go @@ -58,6 +58,14 @@ func (m *mockInstanceClient) Get(id string) (app.InstanceResponse, error) { return m.items[0], nil } +func (m *mockInstanceClient) Find(rbName string, ver string, profile string, labelKeys map[string]string) ([]app.InstanceResponse, error) { + if m.err != nil { + return nil, m.err + } + + return m.items, nil +} + func (m *mockInstanceClient) Delete(id string) error { return m.err } @@ -104,12 +112,14 @@ func TestInstanceCreateHandler(t *testing.T) { "profile-name": "profile1" }`)), expected: app.InstanceResponse{ - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -131,12 +141,14 @@ func TestInstanceCreateHandler(t *testing.T) { instClient: &mockInstanceClient{ items: []app.InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -203,12 +215,14 @@ func TestInstanceGetHandler(t *testing.T) { input: "HaKpys8e", expectedCode: http.StatusOK, expectedResponse: &app.InstanceResponse{ - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -229,12 +243,14 @@ func TestInstanceGetHandler(t *testing.T) { instClient: &mockInstanceClient{ items: []app.InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go index 763aed0d..9894b6ac 100644 --- a/src/k8splugin/internal/app/config_backend.go +++ b/src/k8splugin/internal/app/config_backend.go @@ -343,7 +343,7 @@ func scheduleResources(c chan configResourceList) { data := <-c //TODO: ADD Check to see if Application running ic := NewInstanceClient() - resp, err := ic.Find(data.profile.RBName, data.profile.RBVersion, data.profile.ProfileName) + resp, err := ic.Find(data.profile.RBName, data.profile.RBVersion, data.profile.ProfileName, nil) if err != nil || len(resp) == 0 { log.Println("Error finding a running instance. Retrying later...") time.Sleep(time.Second * 10) @@ -354,7 +354,7 @@ func scheduleResources(c chan configResourceList) { log.Printf("[scheduleResources]: POST %v %v", data.profile, data.resourceTemplates) for _, inst := range resp { k8sClient := KubernetesClient{} - err = k8sClient.init(inst.CloudRegion) + err = k8sClient.init(inst.Request.CloudRegion) if err != nil { log.Printf("Getting CloudRegion Information: %s", err.Error()) //Move onto the next cloud region @@ -374,7 +374,7 @@ func scheduleResources(c chan configResourceList) { log.Printf("[scheduleResources]: DELETE %v %v", data.profile, data.resourceTemplates) for _, inst := range resp { k8sClient := KubernetesClient{} - err = k8sClient.init(inst.CloudRegion) + err = k8sClient.init(inst.Request.CloudRegion) if err != nil { log.Printf("Getting CloudRegion Information: %s", err.Error()) //Move onto the next cloud region diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index 41eca211..19841c01 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -40,20 +40,17 @@ type InstanceRequest struct { // InstanceResponse contains the response from instantiation type InstanceResponse struct { - ID string `json:"id"` - RBName string `json:"rb-name"` - RBVersion string `json:"rb-version"` - ProfileName string `json:"profile-name"` - CloudRegion string `json:"cloud-region"` - Namespace string `json:"namespace"` - Resources []helm.KubernetesResource `json:"resources"` + ID string `json:"id"` + Request InstanceRequest `json:"request"` + Namespace string `json:"namespace"` + Resources []helm.KubernetesResource `json:"resources"` } // InstanceManager is an interface exposes the instantiation functionality type InstanceManager interface { Create(i InstanceRequest) (InstanceResponse, error) Get(id string) (InstanceResponse, error) - Find(rbName string, ver string, profile string) ([]InstanceResponse, error) + Find(rbName string, ver string, profile string, labelKeys map[string]string) ([]InstanceResponse, error) Delete(id string) error } @@ -134,13 +131,10 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { //Compose the return response resp := InstanceResponse{ - ID: id, - RBName: i.RBName, - RBVersion: i.RBVersion, - ProfileName: i.ProfileName, - CloudRegion: i.CloudRegion, - Namespace: profile.Namespace, - Resources: createdResources, + ID: id, + Request: i, + Namespace: profile.Namespace, + Resources: createdResources, } key := InstanceKey{ @@ -180,9 +174,11 @@ func (v *InstanceClient) Get(id string) (InstanceResponse, error) { // 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") +// If labelKeys are provided, the results are filtered based on that. +// It is an AND operation for labelkeys. +func (v *InstanceClient) Find(rbName string, version string, profile string, labelKeys map[string]string) ([]InstanceResponse, error) { + if rbName == "" && len(labelKeys) == 0 { + return []InstanceResponse{}, pkgerrors.New("rbName or labelkeys is required and cannot be empty") } values, err := db.DBconn.ReadAll(v.storeName, v.tagInst) @@ -192,6 +188,7 @@ func (v *InstanceClient) Find(rbName string, version string, profile string) ([] response := []InstanceResponse{} //values is a map[string][]byte +InstanceResponseLoop: for _, value := range values { resp := InstanceResponse{} db.DBconn.Unmarshal(value, &resp) @@ -199,19 +196,45 @@ func (v *InstanceClient) Find(rbName string, version string, profile string) ([] return []InstanceResponse{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value") } - if resp.RBName == rbName { + // Filter by labels provided + if len(labelKeys) != 0 { + for lkey, lvalue := range labelKeys { + //Check if label key exists and get its value + if val, ok := resp.Request.Labels[lkey]; ok { + if lvalue != val { + continue InstanceResponseLoop + } + } else { + continue InstanceResponseLoop + } + } + } + + if rbName != "" { + if resp.Request.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) + //Check if a version is provided and if it matches + if version != "" { + if resp.Request.RBVersion == version { + //Check if a profilename matches or if it is not provided + if profile == "" || resp.Request.ProfileName == profile { + response = append(response, resp) + } } + } else { + //Append all versions as version is not provided + response = append(response, resp) } - } else { - //Append all versions as version is not provided - response = append(response, resp) + } + } else { + response = append(response, resp) + } + } + + //filter the list by labelKeys now + for _, value := range response { + for _, label := range labelKeys { + if _, ok := value.Request.Labels[label]; ok { } } } @@ -227,7 +250,7 @@ func (v *InstanceClient) Delete(id string) error { } k8sClient := KubernetesClient{} - err = k8sClient.init(inst.CloudRegion) + err = k8sClient.init(inst.Request.CloudRegion) if err != nil { return pkgerrors.Wrap(err, "Getting CloudRegion Information") } diff --git a/src/k8splugin/internal/app/instance_test.go b/src/k8splugin/internal/app/instance_test.go index 2fa2115b..ea377482 100644 --- a/src/k8splugin/internal/app/instance_test.go +++ b/src/k8splugin/internal/app/instance_test.go @@ -203,12 +203,14 @@ func TestInstanceGet(t *testing.T) { InstanceKey{ID: "HaKpys8e"}.String(): { "instance": []byte( `{ - "profile-name":"profile1", - "id":"HaKpys8e", + "id":"HaKpys8e", + "request": { + "profile-name":"profile1", + "rb-name":"test-rbdef", + "rb-version":"v1", + "cloud-region":"region1" + }, "namespace":"testnamespace", - "rb-name":"test-rbdef", - "rb-version":"v1", - "cloud-region":"region1", "resources": [ { "GVK": { @@ -233,13 +235,14 @@ func TestInstanceGet(t *testing.T) { } expected := InstanceResponse{ - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", - + ID: "HaKpys8e", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -275,12 +278,14 @@ func TestInstanceGet(t *testing.T) { InstanceKey{ID: "HaKpys8e"}.String(): { "instance": []byte( `{ - "profile-name":"profile1", - "id":"HaKpys8e", + "id":"HaKpys8e", + "request": { + "profile-name":"profile1", + "rb-name":"test-rbdef", + "rb-version":"v1", + "cloud-region":"region1" + }, "namespace":"testnamespace", - "rb-name":"test-rbdef", - "rb-version":"v1", - "cloud-region":"region1", "resources": [ { "GVK": { @@ -329,12 +334,17 @@ func TestInstanceFind(t *testing.T) { InstanceKey{ID: "HaKpys8e"}.String(): { "instance": []byte( `{ - "profile-name":"profile1", - "id":"HaKpys8e", + "id":"HaKpys8e", + "request": { + "profile-name":"profile1", + "rb-name":"test-rbdef", + "rb-version":"v1", + "cloud-region":"region1", + "labels":{ + "vf_module_id": "test-vf-module-id" + } + }, "namespace":"testnamespace", - "rb-name":"test-rbdef", - "rb-version":"v1", - "cloud-region":"region1", "resources": [ { "GVK": { @@ -358,12 +368,14 @@ func TestInstanceFind(t *testing.T) { InstanceKey{ID: "HaKpys8f"}.String(): { "instance": []byte( `{ - "profile-name":"profile2", - "id":"HaKpys8f", + "id":"HaKpys8f", + "request": { + "profile-name":"profile2", + "rb-name":"test-rbdef", + "rb-version":"v1", + "cloud-region":"region1" + }, "namespace":"testnamespace", - "rb-name":"test-rbdef", - "rb-version":"v1", - "cloud-region":"region1", "resources": [ { "GVK": { @@ -387,12 +399,14 @@ func TestInstanceFind(t *testing.T) { InstanceKey{ID: "HaKpys8g"}.String(): { "instance": []byte( `{ - "profile-name":"profile1", - "id":"HaKpys8g", + "id":"HaKpys8g", + "request": { + "profile-name":"profile1", + "rb-name":"test-rbdef", + "rb-version":"v2", + "cloud-region":"region1" + }, "namespace":"testnamespace", - "rb-name":"test-rbdef", - "rb-version":"v2", - "cloud-region":"region1", "resources": [ { "GVK": { @@ -422,13 +436,17 @@ func TestInstanceFind(t *testing.T) { expected := []InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", - + ID: "HaKpys8e", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + Labels: map[string]string{ + "vf_module_id": "test-vf-module-id", + }, + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -447,13 +465,14 @@ func TestInstanceFind(t *testing.T) { }, }, { - ID: "HaKpys8f", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile2", - CloudRegion: "region1", - Namespace: "testnamespace", - + ID: "HaKpys8f", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile2", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -472,13 +491,14 @@ func TestInstanceFind(t *testing.T) { }, }, { - ID: "HaKpys8g", - RBName: "test-rbdef", - RBVersion: "v2", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", - + ID: "HaKpys8g", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v2", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { GVK: schema.GroupVersionKind{ @@ -499,7 +519,7 @@ func TestInstanceFind(t *testing.T) { } ic := NewInstanceClient() name := "test-rbdef" - data, err := ic.Find(name, "", "") + data, err := ic.Find(name, "", "", nil) if err != nil { t.Fatalf("TestInstanceFind returned an error (%s)", err) } @@ -528,12 +548,17 @@ func TestInstanceFind(t *testing.T) { expected := []InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + Labels: map[string]string{ + "vf_module_id": "test-vf-module-id", + }, + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { @@ -553,12 +578,14 @@ func TestInstanceFind(t *testing.T) { }, }, { - ID: "HaKpys8f", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile2", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8f", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile2", + CloudRegion: "region1", + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { @@ -580,7 +607,7 @@ func TestInstanceFind(t *testing.T) { } ic := NewInstanceClient() name := "test-rbdef" - data, err := ic.Find(name, "v1", "") + data, err := ic.Find(name, "v1", "", nil) if err != nil { t.Fatalf("TestInstanceFind returned an error (%s)", err) } @@ -609,12 +636,17 @@ func TestInstanceFind(t *testing.T) { expected := []InstanceResponse{ { - ID: "HaKpys8e", - RBName: "test-rbdef", - RBVersion: "v1", - ProfileName: "profile1", - CloudRegion: "region1", - Namespace: "testnamespace", + ID: "HaKpys8e", + Request: InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + Labels: map[string]string{ + "vf_module_id": "test-vf-module-id", + }, + }, + Namespace: "testnamespace", Resources: []helm.KubernetesResource{ { @@ -636,7 +668,7 @@ func TestInstanceFind(t *testing.T) { } ic := NewInstanceClient() name := "test-rbdef" - data, err := ic.Find(name, "v1", "profile1") + data, err := ic.Find(name, "v1", "profile1", nil) if err != nil { t.Fatalf("TestInstanceFind returned an error (%s)", err) } @@ -695,7 +727,7 @@ func TestInstanceFind(t *testing.T) { ic := NewInstanceClient() name := "non-existing" - resp, _ := ic.Find(name, "", "") + resp, _ := ic.Find(name, "", "", nil) if len(resp) != 0 { t.Fatalf("Expected 0 responses, but got %d", len(resp)) } @@ -726,12 +758,14 @@ func TestInstanceDelete(t *testing.T) { InstanceKey{ID: "HaKpys8e"}.String(): { "instance": []byte( `{ - "profile-name":"profile1", - "id":"HaKpys8e", + "id":"HaKpys8e", + "request": { + "profile-name":"profile1", + "rb-name":"test-rbdef", + "rb-version":"v1", + "cloud-region":"mock_connection" + }, "namespace":"testnamespace", - "rb-name":"test-rbdef", - "rb-version":"v1", - "cloud-region":"mock_connection", "resources": [ { "GVK": { |