aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/api
diff options
context:
space:
mode:
authorrsood <ritu.sood@intel.com>2019-04-10 05:00:04 +0000
committerrsood <ritu.sood@intel.com>2019-04-11 04:53:43 +0000
commit10337dd73e55ecf6327515e70a60aef4325af589 (patch)
treeb580b094ecd444a6fe8b9a8d4892c394ab0d9d3f /src/k8splugin/api
parent9e001472ab04fb0b5b85e38266bacd9a377cc343 (diff)
Day 2 Configuration API's
This patch adds Configuration API's https://wiki.onap.org/display/DW/MultiCloud+K8s-Plugin-service+API%27s Change-Id: I52ebfc5aa980ec8af4a31569d569216e9a2a760c Issue-ID: MULTICLOUD-464 Signed-off-by: rsood <ritu.sood@intel.com>
Diffstat (limited to 'src/k8splugin/api')
-rw-r--r--src/k8splugin/api/api.go26
-rw-r--r--src/k8splugin/api/confighandler.go210
-rw-r--r--src/k8splugin/api/configtemplatehandler.go134
-rw-r--r--src/k8splugin/api/defhandler_test.go10
-rw-r--r--src/k8splugin/api/instancehandler_test.go6
-rw-r--r--src/k8splugin/api/profilehandler_test.go8
6 files changed, 381 insertions, 13 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go
index 54147d2e..2003a809 100644
--- a/src/k8splugin/api/api.go
+++ b/src/k8splugin/api/api.go
@@ -23,7 +23,9 @@ import (
// NewRouter creates a router that registers the various urls that are supported
func NewRouter(defClient rb.DefinitionManager,
profileClient rb.ProfileManager,
- instClient app.InstanceManager) *mux.Router {
+ instClient app.InstanceManager,
+ configClient rb.ConfigManager,
+ templateClient rb.ConfigTemplateManager) *mux.Router {
router := mux.NewRouter()
@@ -61,5 +63,27 @@ func NewRouter(defClient rb.DefinitionManager,
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.getHandler).Methods("GET")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.deleteHandler).Methods("DELETE")
+ // Config Template
+ if templateClient == nil {
+ templateClient = rb.NewConfigTemplateClient()
+ }
+ templateHandler := rbTemplateHandler{client: templateClient}
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template", templateHandler.createHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template/{tname}/content", templateHandler.uploadHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template/{tname}", templateHandler.getHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template/{tname}", templateHandler.deleteHandler).Methods("DELETE")
+
+ // Config value
+ if configClient == nil {
+ configClient = rb.NewConfigClient()
+ }
+ configHandler := rbConfigHandler{client: configClient}
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config", configHandler.createHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config/{cfgname}", configHandler.getHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config/{cfgname}", configHandler.updateHandler).Methods("PUT")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config/{cfgname}", configHandler.deleteHandler).Methods("DELETE")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config/rollback", configHandler.rollbackHandler).Methods("POST")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config/tagit", configHandler.tagitHandler).Methods("POST")
+
return router
}
diff --git a/src/k8splugin/api/confighandler.go b/src/k8splugin/api/confighandler.go
new file mode 100644
index 00000000..93098d61
--- /dev/null
+++ b/src/k8splugin/api/confighandler.go
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2018 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package api
+
+import (
+ "encoding/json"
+ "k8splugin/internal/rb"
+ "net/http"
+
+ "github.com/gorilla/mux"
+)
+
+// Used to store backend implementations objects
+// Also simplifies mocking for unit testing purposes
+type rbConfigHandler struct {
+ // Interface that implements bundle Definition operations
+ // We will set this variable with a mock interface for testing
+ client rb.ConfigManager
+}
+
+// createHandler handles creation of the definition entry in the database
+func (h rbConfigHandler) createHandler(w http.ResponseWriter, r *http.Request) {
+ var p rb.Config
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+
+ if r.Body == nil {
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ }
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Name is required.
+ if p.ConfigName == "" {
+ http.Error(w, "Missing name in POST request", http.StatusBadRequest)
+ return
+ }
+
+ ret, err := h.client.Create(rbName, rbVersion, prName, p)
+ 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
+ }
+}
+
+// getHandler handles GET operations on a particular config
+// Returns a rb.Definition
+func (h rbConfigHandler) getHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+ cfgName := vars["cfgname"]
+
+ ret, err := h.client.Get(rbName, rbVersion, prName, cfgName)
+ 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 {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// deleteHandler handles DELETE operations on a config
+func (h rbConfigHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+ cfgName := vars["cfgname"]
+
+ ret, err := h.client.Delete(rbName, rbVersion, prName, cfgName)
+ 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 {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+}
+
+// UpdateHandler handles Update operations on a particular configuration
+func (h rbConfigHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+ cfgName := vars["cfgname"]
+
+ var p rb.Config
+
+ if r.Body == nil {
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ }
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ ret, err := h.client.Update(rbName, rbVersion, prName, cfgName, p)
+ 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
+ }
+}
+
+// rollbackHandler handles Rollback operations to a specific version
+func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+
+ if r.Body == nil {
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ }
+
+ var p rb.ConfigRollback
+ err := json.NewDecoder(r.Body).Decode(&p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+ err = h.client.Rollback(rbName, rbVersion, prName, p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ w.WriteHeader(http.StatusNoContent)
+}
+
+// tagitHandler handles TAGIT operation
+func (h rbConfigHandler) tagitHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+
+ if r.Body == nil {
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ }
+
+ var p rb.ConfigTagit
+ err := json.NewDecoder(r.Body).Decode(&p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ err = h.client.Tagit(rbName, rbVersion, prName, p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ w.WriteHeader(http.StatusNoContent)
+}
diff --git a/src/k8splugin/api/configtemplatehandler.go b/src/k8splugin/api/configtemplatehandler.go
new file mode 100644
index 00000000..a91165cb
--- /dev/null
+++ b/src/k8splugin/api/configtemplatehandler.go
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2018 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package api
+
+import (
+ "encoding/json"
+ "io"
+ "io/ioutil"
+ "k8splugin/internal/rb"
+ "net/http"
+
+ "github.com/gorilla/mux"
+)
+
+// Used to store backend implementations objects
+// Also simplifies mocking for unit testing purposes
+type rbTemplateHandler struct {
+ // Interface that implements bundle Definition operations
+ // We will set this variable with a mock interface for testing
+ client rb.ConfigTemplateManager
+}
+
+// createHandler handles creation of the template entry in the database
+func (h rbTemplateHandler) createHandler(w http.ResponseWriter, r *http.Request) {
+ var p rb.ConfigTemplate
+
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+ 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 p.TemplateName == "" {
+ http.Error(w, "Missing name in POST request", http.StatusBadRequest)
+ return
+ }
+
+ err = h.client.Create(rbName, rbVersion, p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusNoContent)
+
+}
+
+// uploadHandler handles upload of the template tar file into the database
+func (h rbTemplateHandler) uploadHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ templateName := vars["tname"]
+
+ inpBytes, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Unable to read body", http.StatusBadRequest)
+ return
+ }
+
+ if len(inpBytes) == 0 {
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ }
+
+ err = h.client.Upload(rbName, rbVersion, templateName, inpBytes)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusOK)
+}
+
+// getHandler handles GET operations on a particular template
+func (h rbTemplateHandler) getHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ templateName := vars["tname"]
+
+ ret, err := h.client.Get(rbName, rbVersion, templateName)
+ 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 {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// deleteHandler handles DELETE operations on a template
+func (h rbTemplateHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ templateName := vars["tname"]
+
+ err := h.client.Delete(rbName, rbVersion, templateName)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusNoContent)
+}
diff --git a/src/k8splugin/api/defhandler_test.go b/src/k8splugin/api/defhandler_test.go
index 03189e1d..321eb460 100644
--- a/src/k8splugin/api/defhandler_test.go
+++ b/src/k8splugin/api/defhandler_test.go
@@ -138,7 +138,7 @@ func TestRBDefCreateHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST", "/v1/rb/definition", testCase.reader)
- resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -207,7 +207,7 @@ func TestRBDefListVersionsHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("GET", "/v1/rb/definition/testresourcebundle", nil)
- resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -287,7 +287,7 @@ func TestRBDefGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("GET", "/v1/rb/definition/"+testCase.name+"/"+testCase.version, nil)
- resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -338,7 +338,7 @@ func TestRBDefDeleteHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("DELETE", "/v1/rb/definition/"+testCase.name+"/"+testCase.version, nil)
- resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -395,7 +395,7 @@ func TestRBDefUploadHandler(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST",
"/v1/rb/definition/"+testCase.name+"/"+testCase.version+"/content", testCase.body)
- resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.rbDefClient, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go
index d01d5dfb..ed7135a6 100644
--- a/src/k8splugin/api/instancehandler_test.go
+++ b/src/k8splugin/api/instancehandler_test.go
@@ -137,7 +137,7 @@ func TestInstanceCreateHandler(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST", "/v1/instance", testCase.input)
- resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient))
+ resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil))
if testCase.expectedCode != resp.StatusCode {
body, _ := ioutil.ReadAll(resp.Body)
@@ -210,7 +210,7 @@ func TestInstanceGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("GET", "/v1/instance/"+testCase.input, nil)
- resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient))
+ 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",
@@ -257,7 +257,7 @@ func TestDeleteHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("DELETE", "/v1/instance/"+testCase.input, nil)
- resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient))
+ 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)
diff --git a/src/k8splugin/api/profilehandler_test.go b/src/k8splugin/api/profilehandler_test.go
index 932a0247..2473fea5 100644
--- a/src/k8splugin/api/profilehandler_test.go
+++ b/src/k8splugin/api/profilehandler_test.go
@@ -117,7 +117,7 @@ func TestRBProfileCreateHandler(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST", "/v1/rb/definition/test-rbdef/v1/profile",
testCase.reader)
- resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil))
+ resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -188,7 +188,7 @@ func TestRBProfileGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("GET", "/v1/rb/definition/test-rbdef/v1/profile/"+testCase.prname, nil)
- resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil))
+ resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -236,7 +236,7 @@ func TestRBProfileDeleteHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("DELETE", "/v1/rb/definition/test-rbdef/v1/profile/"+testCase.prname, nil)
- resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil))
+ resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -289,7 +289,7 @@ func TestRBProfileUploadHandler(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST",
"/v1/rb/definition/test-rbdef/v1/profile/"+testCase.prname+"/content", testCase.body)
- resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil))
+ resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {