aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/k8splugin/api/api.go1
-rw-r--r--src/k8splugin/api/brokerhandler.go100
-rw-r--r--src/k8splugin/api/brokerhandler_test.go175
-rw-r--r--src/k8splugin/api/instancehandler_test.go64
-rw-r--r--src/k8splugin/internal/app/config_backend.go6
-rw-r--r--src/k8splugin/internal/app/instance.go81
-rw-r--r--src/k8splugin/internal/app/instance_test.go194
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": {