aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/k8splugin/api')
-rw-r--r--src/k8splugin/api/api.go1
-rw-r--r--src/k8splugin/api/brokerhandler.go12
-rw-r--r--src/k8splugin/api/brokerhandler_test.go41
-rw-r--r--src/k8splugin/api/instancehandler.go151
-rw-r--r--src/k8splugin/api/instancehandler_test.go158
5 files changed, 218 insertions, 145 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go
index 726bd116..c836fc65 100644
--- a/src/k8splugin/api/api.go
+++ b/src/k8splugin/api/api.go
@@ -46,6 +46,7 @@ func NewRouter(defClient rb.DefinitionManager,
"profile-name", "{profile-name}").Methods("GET")
instRouter.HandleFunc("/instance/{instID}", instHandler.getHandler).Methods("GET")
+ instRouter.HandleFunc("/instance/{instID}/status", instHandler.statusHandler).Methods("GET")
instRouter.HandleFunc("/instance/{instID}", instHandler.deleteHandler).Methods("DELETE")
// (TODO): Fix update method
// instRouter.HandleFunc("/{vnfInstanceId}", UpdateHandler).Methods("PUT")
diff --git a/src/k8splugin/api/brokerhandler.go b/src/k8splugin/api/brokerhandler.go
index 669b539f..b377baf1 100644
--- a/src/k8splugin/api/brokerhandler.go
+++ b/src/k8splugin/api/brokerhandler.go
@@ -134,21 +134,21 @@ func (b brokerInstanceHandler) createHandler(w http.ResponseWriter, r *http.Requ
return
}
- rbName := req.getAttributeValue(req.UserDirectives, "definition-name")
+ rbName := req.getAttributeValue(req.SDNCDirectives, "k8s-rb-definition-name")
if rbName == "" {
- http.Error(w, "definition-name is missing from user-directives", http.StatusBadRequest)
+ http.Error(w, "k8s-rb-definition-name is missing from sdnc-directives", http.StatusBadRequest)
return
}
- rbVersion := req.getAttributeValue(req.UserDirectives, "definition-version")
+ rbVersion := req.getAttributeValue(req.SDNCDirectives, "k8s-rb-definition-version")
if rbVersion == "" {
- http.Error(w, "definition-version is missing from user-directives", http.StatusBadRequest)
+ http.Error(w, "k8s-rb-definition-version is missing from sdnc-directives", http.StatusBadRequest)
return
}
- profileName := req.getAttributeValue(req.UserDirectives, "profile-name")
+ profileName := req.getAttributeValue(req.SDNCDirectives, "k8s-rb-profile-name")
if profileName == "" {
- http.Error(w, "profile-name is missing from user-directives", http.StatusBadRequest)
+ http.Error(w, "k8s-rb-profile-name is missing from sdnc-directives", http.StatusBadRequest)
return
}
diff --git a/src/k8splugin/api/brokerhandler_test.go b/src/k8splugin/api/brokerhandler_test.go
index 8ef5e184..00ca3b7b 100644
--- a/src/k8splugin/api/brokerhandler_test.go
+++ b/src/k8splugin/api/brokerhandler_test.go
@@ -54,11 +54,11 @@ func TestBrokerCreateHandler(t *testing.T) {
"user_directives": {
"attributes": [
{
- "attribute_name": "definition-name",
+ "attribute_name": "k8s-rb-definition-name",
"attribute_value": "test-rbdef"
},
{
- "attribute_name": "definition-version",
+ "attribute_name": "k8s-rb-definition-version",
"attribute_value": "v1"
}
]
@@ -67,9 +67,9 @@ func TestBrokerCreateHandler(t *testing.T) {
expectedCode: http.StatusBadRequest,
},
{
- label: "Succesfully create an Instance",
+ label: "Deprecated parameters passed (user_directives)",
input: bytes.NewBuffer([]byte(`{
- "vf-module-model-customization-id": "84sdfkio938",
+ "vf-module-model-customization-id": "97sdfkio168",
"sdnc_directives": {
"attributes": [
{
@@ -81,15 +81,42 @@ func TestBrokerCreateHandler(t *testing.T) {
"user_directives": {
"attributes": [
{
- "attribute_name": "definition-name",
+ "attribute_name": "rb-definition-name",
+ "attribute_value": "test-rbdef"
+ },
+ {
+ "attribute_name": "rb-definition-version",
+ "attribute_value": "v1"
+ },
+ {
+ "attribute_name": "rb-profile-name",
+ "attribute_value": "profile1"
+ }
+ ]
+ }
+ }`)),
+ expectedCode: http.StatusBadRequest,
+ },
+ {
+ 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"
+ },
+ {
+ "attribute_name": "k8s-rb-definition-name",
"attribute_value": "test-rbdef"
},
{
- "attribute_name": "definition-version",
+ "attribute_name": "k8s-rb-definition-version",
"attribute_value": "v1"
},
{
- "attribute_name": "profile-name",
+ "attribute_name": "k8s-rb-profile-name",
"attribute_value": "profile1"
}
]
diff --git a/src/k8splugin/api/instancehandler.go b/src/k8splugin/api/instancehandler.go
index be8e64fa..b0437426 100644
--- a/src/k8splugin/api/instancehandler.go
+++ b/src/k8splugin/api/instancehandler.go
@@ -20,6 +20,7 @@ import (
"net/http"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/app"
+ log "github.com/onap/multicloud-k8s/src/k8splugin/internal/logutils"
"github.com/gorilla/mux"
pkgerrors "github.com/pkg/errors"
@@ -36,14 +37,25 @@ func (i instanceHandler) validateBody(body interface{}) error {
switch b := body.(type) {
case app.InstanceRequest:
if b.CloudRegion == "" {
+ log.Error("CreateVnfRequest Bad Request", log.Fields{
+ "cloudRegion": "Missing CloudRegion in POST request",
+ })
werr := pkgerrors.Wrap(errors.New("Invalid/Missing CloudRegion in POST request"), "CreateVnfRequest bad request")
return werr
}
if b.RBName == "" || b.RBVersion == "" {
+ log.Error("CreateVnfRequest Bad Request", log.Fields{
+ "message": "One of RBName, RBVersion is missing",
+ "RBName": b.RBName,
+ "RBVersion": b.RBVersion,
+ })
werr := pkgerrors.Wrap(errors.New("Invalid/Missing resource bundle parameters in POST request"), "CreateVnfRequest bad request")
return werr
}
if b.ProfileName == "" {
+ log.Error("CreateVnfRequest bad request", log.Fields{
+ "ProfileName": "Missing profile name in POST request",
+ })
werr := pkgerrors.Wrap(errors.New("Invalid/Missing profile name in POST request"), "CreateVnfRequest bad request")
return werr
}
@@ -57,9 +69,15 @@ func (i instanceHandler) createHandler(w http.ResponseWriter, r *http.Request) {
err := json.NewDecoder(r.Body).Decode(&resource)
switch {
case err == io.EOF:
+ log.Error("Body Empty", log.Fields{
+ "error": io.EOF,
+ })
http.Error(w, "Body empty", http.StatusBadRequest)
return
case err != nil:
+ log.Error("Error unmarshaling Body", log.Fields{
+ "error": err,
+ })
http.Error(w, err.Error(), http.StatusUnprocessableEntity)
return
}
@@ -67,12 +85,19 @@ func (i instanceHandler) createHandler(w http.ResponseWriter, r *http.Request) {
// Check body for expected parameters
err = i.validateBody(resource)
if err != nil {
+ log.Error("Invalid Parameters in Body", log.Fields{
+ "error": err,
+ })
http.Error(w, err.Error(), http.StatusUnprocessableEntity)
return
}
resp, err := i.client.Create(resource)
if err != nil {
+ log.Error("Error Creating Resource", log.Fields{
+ "error": err,
+ "resource": resource,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -81,6 +106,10 @@ func (i instanceHandler) createHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusCreated)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
+ log.Error("Error Marshaling Response", log.Fields{
+ "error": err,
+ "response": resp,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -93,6 +122,10 @@ func (i instanceHandler) getHandler(w http.ResponseWriter, r *http.Request) {
resp, err := i.client.Get(id)
if err != nil {
+ log.Error("Error getting Instance", log.Fields{
+ "error": err,
+ "id": id,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -101,6 +134,38 @@ func (i instanceHandler) getHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
+ log.Error("Error Marshaling Response", log.Fields{
+ "error": err,
+ "response": resp,
+ })
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// statusHandler retrieves status about an instance via the ID
+func (i instanceHandler) statusHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ id := vars["instID"]
+
+ resp, err := i.client.Status(id)
+ if err != nil {
+ log.Error("Error getting Status", log.Fields{
+ "error": err,
+ "id": id,
+ })
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(resp)
+ if err != nil {
+ log.Error("Error Marshaling Response", log.Fields{
+ "error": err,
+ "response": resp,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -113,10 +178,16 @@ func (i instanceHandler) listHandler(w http.ResponseWriter, r *http.Request) {
//Which will list all instances
rbName := r.FormValue("rb-name")
rbVersion := r.FormValue("rb-version")
- ProfileName := r.FormValue("profile-name")
+ profileName := r.FormValue("profile-name")
- resp, err := i.client.List(rbName, rbVersion, ProfileName)
+ resp, err := i.client.List(rbName, rbVersion, profileName)
if err != nil {
+ log.Error("Error listing instances", log.Fields{
+ "error": err,
+ "rb-name": rbName,
+ "rb-version": rbVersion,
+ "profile-name": profileName,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -125,6 +196,10 @@ func (i instanceHandler) listHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
+ log.Error("Error Marshaling Response", log.Fields{
+ "error": err,
+ "response": resp,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -137,6 +212,9 @@ func (i instanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
err := i.client.Delete(id)
if err != nil {
+ log.Error("Error Deleting Instance", log.Fields{
+ "error": err,
+ })
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -144,72 +222,3 @@ func (i instanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusAccepted)
}
-
-// // UpdateHandler method to update a VNF instance.
-// func UpdateHandler(w http.ResponseWriter, r *http.Request) {
-// vars := mux.Vars(r)
-// id := vars["vnfInstanceId"]
-
-// var resource UpdateVnfRequest
-
-// if r.Body == nil {
-// http.Error(w, "Body empty", http.StatusBadRequest)
-// return
-// }
-
-// err := json.NewDecoder(r.Body).Decode(&resource)
-// if err != nil {
-// http.Error(w, err.Error(), http.StatusUnprocessableEntity)
-// return
-// }
-
-// err = validateBody(resource)
-// if err != nil {
-// http.Error(w, err.Error(), http.StatusUnprocessableEntity)
-// return
-// }
-
-// kubeData, err := utils.ReadCSARFromFileSystem(resource.CsarID)
-
-// if kubeData.Deployment == nil {
-// werr := pkgerrors.Wrap(err, "Update VNF deployment error")
-// http.Error(w, werr.Error(), http.StatusInternalServerError)
-// return
-// }
-// kubeData.Deployment.SetUID(types.UID(id))
-
-// if err != nil {
-// werr := pkgerrors.Wrap(err, "Update VNF deployment information error")
-// http.Error(w, werr.Error(), http.StatusInternalServerError)
-// return
-// }
-
-// // (TODO): Read kubeconfig for specific Cloud Region from local file system
-// // if present or download it from AAI
-// s, err := NewVNFInstanceService("../kubeconfig/config")
-// if err != nil {
-// http.Error(w, err.Error(), http.StatusInternalServerError)
-// return
-// }
-
-// err = s.Client.UpdateDeployment(kubeData.Deployment, resource.Namespace)
-// if err != nil {
-// werr := pkgerrors.Wrap(err, "Update VNF error")
-
-// http.Error(w, werr.Error(), http.StatusInternalServerError)
-// return
-// }
-
-// resp := UpdateVnfResponse{
-// DeploymentID: id,
-// }
-
-// w.Header().Set("Content-Type", "application/json")
-// w.WriteHeader(http.StatusCreated)
-
-// err = json.NewEncoder(w).Encode(resp)
-// if err != nil {
-// werr := pkgerrors.Wrap(err, "Parsing output of new VNF error")
-// http.Error(w, werr.Error(), http.StatusInternalServerError)
-// }
-// }
diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go
index 418054ec..7b6594cf 100644
--- a/src/k8splugin/api/instancehandler_test.go
+++ b/src/k8splugin/api/instancehandler_test.go
@@ -39,9 +39,10 @@ type mockInstanceClient struct {
app.InstanceManager
// Items and err will be used to customize each test
// via a localized instantiation of mockInstanceClient
- items []app.InstanceResponse
- miniitems []app.InstanceMiniResponse
- err error
+ items []app.InstanceResponse
+ miniitems []app.InstanceMiniResponse
+ statusItem app.InstanceStatus
+ err error
}
func (m *mockInstanceClient) Create(inp app.InstanceRequest) (app.InstanceResponse, error) {
@@ -60,6 +61,14 @@ func (m *mockInstanceClient) Get(id string) (app.InstanceResponse, error) {
return m.items[0], nil
}
+func (m *mockInstanceClient) Status(id string) (app.InstanceStatus, error) {
+ if m.err != nil {
+ return app.InstanceStatus{}, m.err
+ }
+
+ return m.statusItem, nil
+}
+
func (m *mockInstanceClient) List(rbname, rbversion, profilename string) ([]app.InstanceMiniResponse, error) {
if m.err != nil {
return []app.InstanceMiniResponse{}, m.err
@@ -307,6 +316,91 @@ func TestInstanceGetHandler(t *testing.T) {
}
}
+func TestStatusHandler(t *testing.T) {
+ testCases := []struct {
+ label string
+ input string
+ expectedCode int
+ expectedResponse *app.InstanceStatus
+ instClient *mockInstanceClient
+ }{
+ {
+ label: "Fail to Get Status",
+ input: "HaKpys8e",
+ expectedCode: http.StatusInternalServerError,
+ instClient: &mockInstanceClient{
+ err: pkgerrors.New("Internal error"),
+ },
+ },
+ {
+ label: "Succesful GET Status",
+ input: "HaKpys8e",
+ expectedCode: http.StatusOK,
+ expectedResponse: &app.InstanceStatus{
+ Request: app.InstanceRequest{
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile1",
+ CloudRegion: "region1",
+ },
+ Ready: true,
+ ResourceCount: 2,
+ PodStatuses: []app.PodStatus{
+ {
+ Name: "test-pod1",
+ Namespace: "default",
+ Ready: true,
+ IPAddresses: []string{"192.168.1.1", "192.168.2.1"},
+ },
+ {
+ Name: "test-pod2",
+ Namespace: "default",
+ Ready: true,
+ IPAddresses: []string{"192.168.3.1", "192.168.5.1"},
+ },
+ },
+ },
+ instClient: &mockInstanceClient{
+ statusItem: app.InstanceStatus{
+ Request: app.InstanceRequest{
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile1",
+ CloudRegion: "region1",
+ },
+ Ready: true,
+ ResourceCount: 2,
+ PodStatuses: []app.PodStatus{
+ {
+ Name: "test-pod1",
+ Namespace: "default",
+ Ready: true,
+ IPAddresses: []string{"192.168.1.1", "192.168.2.1"},
+ },
+ {
+ Name: "test-pod2",
+ Namespace: "default",
+ Ready: true,
+ IPAddresses: []string{"192.168.3.1", "192.168.5.1"},
+ },
+ },
+ },
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ request := httptest.NewRequest("GET", "/v1/instance/"+testCase.input+"/status", nil)
+ resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil, nil))
+
+ if testCase.expectedCode != resp.StatusCode {
+ t.Fatalf("Request method returned: %v and it was expected: %v", resp.StatusCode, testCase.expectedCode)
+ }
+ })
+ }
+}
+
func TestInstanceListHandler(t *testing.T) {
testCases := []struct {
label string
@@ -488,61 +582,3 @@ func TestDeleteHandler(t *testing.T) {
})
}
}
-
-// TODO: Update this test when the UpdateVNF endpoint is fixed.
-/*
-func TestVNFInstanceUpdate(t *testing.T) {
- t.Run("Succesful update a VNF", func(t *testing.T) {
- payload := []byte(`{
- "cloud_region_id": "region1",
- "csar_id": "UUID-1",
- "oof_parameters": [{
- "key1": "value1",
- "key2": "value2",
- "key3": {}
- }],
- "network_parameters": {
- "oam_ip_address": {
- "connection_point": "string",
- "ip_address": "string",
- "workload_name": "string"
- }
- }
- }`)
- expected := &UpdateVnfResponse{
- DeploymentID: "1",
- }
-
- var result UpdateVnfResponse
-
- req := httptest.NewRequest("PUT", "/v1/vnf_instances/1", bytes.NewBuffer(payload))
-
- GetVNFClient = func(configPath string) (krd.VNFInstanceClientInterface, error) {
- return &mockClient{
- update: func() error {
- return nil
- },
- }, nil
- }
- utils.ReadCSARFromFileSystem = func(csarID string) (*krd.KubernetesData, error) {
- kubeData := &krd.KubernetesData{
- Deployment: &appsV1.Deployment{},
- Service: &coreV1.Service{},
- }
- return kubeData, nil
- }
-
- response := executeRequest(req)
- checkResponseCode(t, http.StatusCreated, response.Code)
-
- err := json.NewDecoder(response.Body).Decode(&result)
- if err != nil {
- t.Fatalf("TestVNFInstanceUpdate returned:\n result=%v\n expected=%v", err, expected.DeploymentID)
- }
-
- if resp.DeploymentID != expected.DeploymentID {
- t.Fatalf("TestVNFInstanceUpdate returned:\n result=%v\n expected=%v", resp.DeploymentID, expected.DeploymentID)
- }
- })
-}
-*/