aboutsummaryrefslogtreecommitdiffstats
path: root/src/orchestrator/api
diff options
context:
space:
mode:
authorEric Multanen <eric.w.multanen@intel.com>2020-04-16 10:44:06 -0700
committerEric Multanen <eric.w.multanen@intel.com>2020-04-22 23:30:24 -0700
commit0b59486c82a9786c85438f6352636b19b83e1021 (patch)
tree06af2aa3929357f9cc4e328cd09c7fce554cbf43 /src/orchestrator/api
parent9e086eb494441de0967b84d0f04d3b4dc7e753c2 (diff)
Controller API support
Add controller API support as baseline for adding gRPC framework. Issue-ID: MULTICLOUD-1019 Signed-off-by: Eric Multanen <eric.w.multanen@intel.com> Change-Id: Ifd522a0eefbb8e54be45cc62003d3809283c9bfe
Diffstat (limited to 'src/orchestrator/api')
-rw-r--r--src/orchestrator/api/api.go3
-rw-r--r--src/orchestrator/api/controllerhandler.go106
-rw-r--r--src/orchestrator/api/controllerhandler_test.go57
3 files changed, 144 insertions, 22 deletions
diff --git a/src/orchestrator/api/api.go b/src/orchestrator/api/api.go
index 6277d994..8b4b91a1 100644
--- a/src/orchestrator/api/api.go
+++ b/src/orchestrator/api/api.go
@@ -111,7 +111,8 @@ func NewRouter(projectClient moduleLib.ProjectManager,
router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/composite-profiles/{composite-profile-name}/profiles/{app-profile}", appProfileHandler.deleteAppProfileHandler).Methods("DELETE")
router.HandleFunc("/controllers", controlHandler.createHandler).Methods("POST")
- router.HandleFunc("/controllers", controlHandler.createHandler).Methods("PUT")
+ router.HandleFunc("/controllers", controlHandler.getHandler).Methods("GET")
+ router.HandleFunc("/controllers/{controller-name}", controlHandler.putHandler).Methods("PUT")
router.HandleFunc("/controllers/{controller-name}", controlHandler.getHandler).Methods("GET")
router.HandleFunc("/controllers/{controller-name}", controlHandler.deleteHandler).Methods("DELETE")
//setting routes for genericPlacementIntent
diff --git a/src/orchestrator/api/controllerhandler.go b/src/orchestrator/api/controllerhandler.go
index 4f98c023..1dad2bf8 100644
--- a/src/orchestrator/api/controllerhandler.go
+++ b/src/orchestrator/api/controllerhandler.go
@@ -22,7 +22,9 @@ import (
"net/http"
"github.com/gorilla/mux"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
+ pkgerrors "github.com/pkg/errors"
)
// Used to store backend implementations objects
@@ -33,6 +35,43 @@ type controllerHandler struct {
client moduleLib.ControllerManager
}
+// Check for valid format of input parameters
+func validateControllerInputs(c moduleLib.Controller) error {
+ // validate metadata
+ err := moduleLib.IsValidMetadata(c.Metadata)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Invalid controller metadata")
+ }
+
+ errs := validation.IsValidName(c.Spec.Host)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid host name for controller %v, errors: %v", c.Spec.Host, errs)
+ }
+
+ errs = validation.IsValidNumber(c.Spec.Port, 0, 65535)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid controller port [%v], errors: %v", c.Spec.Port, errs)
+ }
+
+ found := false
+ for _, val := range moduleLib.CONTROLLER_TYPES {
+ if c.Spec.Type == val {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return pkgerrors.Errorf("Invalid controller type: %v", c.Spec.Type)
+ }
+
+ errs = validation.IsValidNumber(c.Spec.Priority, moduleLib.MinControllerPriority, moduleLib.MaxControllerPriority)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid controller priority = [%v], errors: %v", c.Spec.Priority, errs)
+ }
+
+ return nil
+}
+
// Create handles creation of the controller entry in the database
func (h controllerHandler) createHandler(w http.ResponseWriter, r *http.Request) {
var m moduleLib.Controller
@@ -48,12 +87,12 @@ func (h controllerHandler) createHandler(w http.ResponseWriter, r *http.Request)
}
// Name is required.
- if m.Name == "" {
+ if m.Metadata.Name == "" {
http.Error(w, "Missing name in POST request", http.StatusBadRequest)
return
}
- ret, err := h.client.CreateController(m)
+ ret, err := h.client.CreateController(m, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -68,19 +107,74 @@ func (h controllerHandler) createHandler(w http.ResponseWriter, r *http.Request)
}
}
-// Get handles GET operations on a particular controller Name
-// Returns a controller
-func (h controllerHandler) getHandler(w http.ResponseWriter, r *http.Request) {
+// Put handles creation or update of the controller entry in the database
+func (h controllerHandler) putHandler(w http.ResponseWriter, r *http.Request) {
+ var m moduleLib.Controller
vars := mux.Vars(r)
name := vars["controller-name"]
- ret, err := h.client.GetController(name)
+ err := json.NewDecoder(r.Body).Decode(&m)
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Name is required.
+ if m.Metadata.Name == "" {
+ http.Error(w, "Missing name in POST request", http.StatusBadRequest)
+ return
+ }
+
+ // name in URL should match name in body
+ if m.Metadata.Name != name {
+ http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest)
+ return
+ }
+
+ ret, err := h.client.CreateController(m, true)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Get handles GET operations on a particular controller Name
+// Returns a controller
+func (h controllerHandler) getHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ name := vars["controller-name"]
+ var ret interface{}
+ var err error
+
+ // handle the get all controllers case
+ if len(name) == 0 {
+ ret, err = h.client.GetControllers()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ } else {
+
+ ret, err = h.client.GetController(name)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ }
+
+ w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(ret)
if err != nil {
diff --git a/src/orchestrator/api/controllerhandler_test.go b/src/orchestrator/api/controllerhandler_test.go
index 3c543cb8..a2f93ea7 100644
--- a/src/orchestrator/api/controllerhandler_test.go
+++ b/src/orchestrator/api/controllerhandler_test.go
@@ -40,7 +40,7 @@ type mockControllerManager struct {
Err error
}
-func (m *mockControllerManager) CreateController(inp moduleLib.Controller) (moduleLib.Controller, error) {
+func (m *mockControllerManager) CreateController(inp moduleLib.Controller, mayExist bool) (moduleLib.Controller, error) {
if m.Err != nil {
return moduleLib.Controller{}, m.Err
}
@@ -56,6 +56,14 @@ func (m *mockControllerManager) GetController(name string) (moduleLib.Controller
return m.Items[0], nil
}
+func (m *mockControllerManager) GetControllers() ([]moduleLib.Controller, error) {
+ if m.Err != nil {
+ return []moduleLib.Controller{}, m.Err
+ }
+
+ return m.Items, nil
+}
+
func (m *mockControllerManager) DeleteController(name string) error {
return m.Err
}
@@ -77,22 +85,33 @@ func TestControllerCreateHandler(t *testing.T) {
label: "Create Controller",
expectedCode: http.StatusCreated,
reader: bytes.NewBuffer([]byte(`{
- "name":"testController",
+ "metadata": {
+ "name":"testController"
+ },
+ "spec": {
"ip-address":"10.188.234.1",
- "port":8080
+ "port":8080 }
}`)),
expected: moduleLib.Controller{
- Name: "testController",
- Host: "10.188.234.1",
- Port: 8080,
+ Metadata: moduleLib.Metadata{
+ Name: "testController",
+ },
+ Spec: moduleLib.ControllerSpec{
+ Host: "10.188.234.1",
+ Port: 8080,
+ },
},
controllerClient: &mockControllerManager{
//Items that will be returned by the mocked Client
Items: []moduleLib.Controller{
{
- Name: "testController",
- Host: "10.188.234.1",
- Port: 8080,
+ Metadata: moduleLib.Metadata{
+ Name: "testController",
+ },
+ Spec: moduleLib.ControllerSpec{
+ Host: "10.188.234.1",
+ Port: 8080,
+ },
},
},
},
@@ -144,17 +163,25 @@ func TestControllerGetHandler(t *testing.T) {
label: "Get Controller",
expectedCode: http.StatusOK,
expected: moduleLib.Controller{
- Name: "testController",
- Host: "10.188.234.1",
- Port: 8080,
+ Metadata: moduleLib.Metadata{
+ Name: "testController",
+ },
+ Spec: moduleLib.ControllerSpec{
+ Host: "10.188.234.1",
+ Port: 8080,
+ },
},
name: "testController",
controllerClient: &mockControllerManager{
Items: []moduleLib.Controller{
{
- Name: "testController",
- Host: "10.188.234.1",
- Port: 8080,
+ Metadata: moduleLib.Metadata{
+ Name: "testController",
+ },
+ Spec: moduleLib.ControllerSpec{
+ Host: "10.188.234.1",
+ Port: 8080,
+ },
},
},
},