summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Rajewski <lukasz.rajewski@orange.com>2021-10-15 12:11:44 +0200
committerLukasz Rajewski <lukasz.rajewski@orange.com>2021-10-15 12:12:44 +0200
commitb2f51225bc78212682fd087a4ef8a67c51a94188 (patch)
tree6984ad7ca8a6af18658957d4fa6be9d029d11111
parent7e265aa8286a5e77ddc63fe2f9e20c776792e2f1 (diff)
Expose Update Handlers
Expose Update Handlers for Definition, Profile and Config Tmpl Issue-ID: MULTICLOUD-1410 Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com> Change-Id: Ibe6fe05458f2af28f3e1ca14a54492a4bae19362
-rw-r--r--src/k8splugin/api/api.go3
-rw-r--r--src/k8splugin/api/configtemplatehandler.go53
-rw-r--r--src/k8splugin/api/defhandler.go52
-rw-r--r--src/k8splugin/api/profilehandler.go64
-rw-r--r--src/k8splugin/api/profilehandler_test.go2
-rw-r--r--src/k8splugin/internal/rb/config_template.go24
-rw-r--r--src/k8splugin/internal/rb/definition.go25
-rw-r--r--src/k8splugin/internal/rb/definition_test.go3
-rw-r--r--src/k8splugin/internal/rb/profile.go25
-rw-r--r--src/k8splugin/internal/rb/profile_test.go2
10 files changed, 227 insertions, 26 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go
index ed23f392..a3e53dc8 100644
--- a/src/k8splugin/api/api.go
+++ b/src/k8splugin/api/api.go
@@ -104,6 +104,7 @@ func NewRouter(defClient rb.DefinitionManager,
resRouter.HandleFunc("/definition/{rbname}", defHandler.listVersionsHandler).Methods("GET")
resRouter.HandleFunc("/definition", defHandler.listAllHandler).Methods("GET")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}", defHandler.getHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}", defHandler.updateHandler).Methods("PUT")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}", defHandler.deleteHandler).Methods("DELETE")
//Setup resource bundle profile routes
@@ -115,6 +116,7 @@ func NewRouter(defClient rb.DefinitionManager,
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile", profileHandler.listHandler).Methods("GET")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/content", profileHandler.uploadHandler).Methods("POST")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.getHandler).Methods("GET")
+ resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.updateHandler).Methods("PUT")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.deleteHandler).Methods("DELETE")
// Config Template
@@ -126,6 +128,7 @@ func NewRouter(defClient rb.DefinitionManager,
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template", templateHandler.listHandler).Methods("GET")
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.updateHandler).Methods("PUT")
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template/{tname}", templateHandler.deleteHandler).Methods("DELETE")
// Config value
diff --git a/src/k8splugin/api/configtemplatehandler.go b/src/k8splugin/api/configtemplatehandler.go
index 0560c7ea..e8750fd8 100644
--- a/src/k8splugin/api/configtemplatehandler.go
+++ b/src/k8splugin/api/configtemplatehandler.go
@@ -59,7 +59,7 @@ func (h rbTemplateHandler) createHandler(w http.ResponseWriter, r *http.Request)
return
}
- err = h.client.Create(rbName, rbVersion, p)
+ err = h.client.CreateOrUpdate(rbName, rbVersion, p, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -123,6 +123,57 @@ func (h rbTemplateHandler) getHandler(w http.ResponseWriter, r *http.Request) {
}
}
+// createHandler handles creation of the template entry in the database
+func (h rbTemplateHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
+ var p rb.ConfigTemplate
+
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ templateName := vars["tname"]
+
+ 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
+ }
+
+ ret, err := h.client.Get(rbName, rbVersion, templateName)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ if p.TemplateName != "" && p.TemplateName != ret.TemplateName {
+ http.Error(w, "Template name mismatch", http.StatusBadRequest)
+ return
+ }
+
+ err = h.client.CreateOrUpdate(rbName, rbVersion, p, 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(p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
// getHandler handles GET operations on a particular template
func (h rbTemplateHandler) listHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
diff --git a/src/k8splugin/api/defhandler.go b/src/k8splugin/api/defhandler.go
index 480d4be5..3dea8ade 100644
--- a/src/k8splugin/api/defhandler.go
+++ b/src/k8splugin/api/defhandler.go
@@ -35,7 +35,7 @@ type rbDefinitionHandler struct {
client rb.DefinitionManager
}
-// createHandler handles creation of the definition entry in the database
+// createOrUpdateHandler handles creation of the definition entry in the database
func (h rbDefinitionHandler) createHandler(w http.ResponseWriter, r *http.Request) {
var v rb.Definition
@@ -48,20 +48,64 @@ func (h rbDefinitionHandler) createHandler(w http.ResponseWriter, r *http.Reques
http.Error(w, err.Error(), http.StatusUnprocessableEntity)
return
}
+ h.createOrUpdateHandler(v, w, false)
+}
+
+// createOrUpdateHandler handles creation of the definition entry in the database
+func (h rbDefinitionHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ name := vars["rbname"]
+ version := vars["rbversion"]
+
+ var v rb.Definition
+ err := json.NewDecoder(r.Body).Decode(&v)
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ if v.RBVersion != "" && v.RBVersion != version {
+ http.Error(w, "RB version mismatch", http.StatusBadRequest)
+ return
+ }
+
+ if v.RBName != "" && v.RBName != name {
+ http.Error(w, "RB name mismatch", http.StatusBadRequest)
+ return
+ }
+
+ v.RBVersion = version
+ v.RBName = name
+
+ h.createOrUpdateHandler(v, w, true)
+}
+
+// createOrUpdateHandler handles creation of the definition entry in the database
+func (h rbDefinitionHandler) createOrUpdateHandler(v rb.Definition, w http.ResponseWriter, update bool) {
// Name is required.
if v.RBName == "" {
- http.Error(w, "Missing name in POST request", http.StatusBadRequest)
+ http.Error(w, "Missing name in request", http.StatusBadRequest)
return
}
// Version is required.
if v.RBVersion == "" {
- http.Error(w, "Missing version in POST request", http.StatusBadRequest)
+ http.Error(w, "Missing version in request", http.StatusBadRequest)
return
}
- ret, err := h.client.Create(v)
+ var ret rb.Definition
+ var err error
+ if update {
+ ret, err = h.client.Update(v)
+ } else {
+ ret, err = h.client.Create(v)
+ }
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/k8splugin/api/profilehandler.go b/src/k8splugin/api/profilehandler.go
index acd23060..1babc4ae 100644
--- a/src/k8splugin/api/profilehandler.go
+++ b/src/k8splugin/api/profilehandler.go
@@ -56,7 +56,7 @@ func (h rbProfileHandler) createHandler(w http.ResponseWriter, r *http.Request)
return
}
- ret, err := h.client.Create(p)
+ ret, err := h.client.CreateOrUpdate(p, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -127,6 +127,68 @@ func (h rbProfileHandler) getHandler(w http.ResponseWriter, r *http.Request) {
}
}
+// updateHandler updates Profile Key in the database
+// Returns an rb.Profile
+func (h rbProfileHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ rbName := vars["rbname"]
+ rbVersion := vars["rbversion"]
+ prName := vars["prname"]
+
+ ret, err := h.client.Get(rbName, rbVersion, prName)
+ if err != nil {
+ // Separate "Not found" from generic DB errors
+ if strings.Contains(err.Error(), "Error finding") {
+ http.Error(w, err.Error(), http.StatusNotFound)
+ return
+ } else {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ }
+
+ var p rb.Profile
+
+ 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
+ }
+
+ if p.ProfileName != "" && p.ProfileName != ret.ProfileName {
+ http.Error(w, "Profile name mismatch", http.StatusBadRequest)
+ return
+ }
+
+ if p.RBVersion != "" && p.RBVersion != ret.RBVersion {
+ http.Error(w, "RB version mismatch", http.StatusBadRequest)
+ return
+ }
+
+ if p.RBName != "" && p.RBName != ret.RBName {
+ http.Error(w, "RB name mismatch", http.StatusBadRequest)
+ return
+ }
+
+ p.ProfileName = ret.ProfileName
+ p.RBVersion = ret.RBVersion
+ p.RBName = ret.RBName
+
+ ret, err = h.client.CreateOrUpdate(p, true)
+
+ 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
+ }
+}
+
// getHandler gets all profiles of a Resource Bundle Key in the database
// Returns a list of rb.Profile
func (h rbProfileHandler) listHandler(w http.ResponseWriter, r *http.Request) {
diff --git a/src/k8splugin/api/profilehandler_test.go b/src/k8splugin/api/profilehandler_test.go
index 32d0061f..181b775b 100644
--- a/src/k8splugin/api/profilehandler_test.go
+++ b/src/k8splugin/api/profilehandler_test.go
@@ -42,7 +42,7 @@ type mockRBProfile struct {
Err error
}
-func (m *mockRBProfile) Create(inp rb.Profile) (rb.Profile, error) {
+func (m *mockRBProfile) CreateOrUpdate(inp rb.Profile, update bool) (rb.Profile, error) {
if m.Err != nil {
return rb.Profile{}, m.Err
}
diff --git a/src/k8splugin/internal/rb/config_template.go b/src/k8splugin/internal/rb/config_template.go
index b84b6461..97fe0fb4 100644
--- a/src/k8splugin/internal/rb/config_template.go
+++ b/src/k8splugin/internal/rb/config_template.go
@@ -41,7 +41,7 @@ type ConfigTemplate struct {
// ConfigTemplateManager is an interface exposes the resource bundle ConfigTemplate functionality
type ConfigTemplateManager interface {
- Create(rbName, rbVersion string, p ConfigTemplate) error
+ CreateOrUpdate(rbName, rbVersion string, p ConfigTemplate, update bool) error
Get(rbName, rbVersion, templateName string) (ConfigTemplate, error)
List(rbName, rbVersion string) ([]ConfigTemplate, error)
Delete(rbName, rbVersion, templateName string) error
@@ -84,8 +84,8 @@ func NewConfigTemplateClient() *ConfigTemplateClient {
}
}
-// Create an entry for the resource bundle ConfigTemplate in the database
-func (v *ConfigTemplateClient) Create(rbName, rbVersion string, p ConfigTemplate) error {
+// CreateOrUpdate an entry for the resource bundle ConfigTemplate in the database
+func (v *ConfigTemplateClient) CreateOrUpdate(rbName, rbVersion string, p ConfigTemplate, update bool) error {
log.Printf("[ConfigiTemplate]: create %s", rbName)
// Name is required
@@ -95,9 +95,12 @@ func (v *ConfigTemplateClient) Create(rbName, rbVersion string, p ConfigTemplate
//Check if ConfigTemplate already exists
_, err := v.Get(rbName, rbVersion, p.TemplateName)
- if err == nil {
+ if err == nil && !update {
return pkgerrors.New(" ConfigTemplate already exists for this Definition")
}
+ if err != nil && update {
+ return pkgerrors.New(" ConfigTemplate does not exist for this Definition")
+ }
//Check if provided resource bundle information is valid
_, err = NewDefinitionClient().Get(rbName, rbVersion)
@@ -111,9 +114,16 @@ func (v *ConfigTemplateClient) Create(rbName, rbVersion string, p ConfigTemplate
TemplateName: p.TemplateName,
}
- err = db.DBconn.Create(v.storeName, key, v.tagMeta, p)
- if err != nil {
- return pkgerrors.Wrap(err, "Creating ConfigTemplate DB Entry")
+ if update {
+ err = db.DBconn.Update(v.storeName, key, v.tagMeta, p)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Updating ConfigTemplate DB Entry")
+ }
+ } else {
+ err = db.DBconn.Create(v.storeName, key, v.tagMeta, p)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Creating ConfigTemplate DB Entry")
+ }
}
return nil
diff --git a/src/k8splugin/internal/rb/definition.go b/src/k8splugin/internal/rb/definition.go
index 73ea44da..aa76afaa 100644
--- a/src/k8splugin/internal/rb/definition.go
+++ b/src/k8splugin/internal/rb/definition.go
@@ -61,6 +61,7 @@ func (dk DefinitionKey) String() string {
// DefinitionManager is an interface exposes the resource bundle definition functionality
type DefinitionManager interface {
Create(def Definition) (Definition, error)
+ Update(def Definition) (Definition, error)
List(name string) ([]Definition, error)
Get(name string, version string) (Definition, error)
Delete(name string, version string) error
@@ -104,13 +105,13 @@ func (v *DefinitionClient) Create(def Definition) (Definition, error) {
// Create a default profile automatically
prc := NewProfileClient()
- pr, err := prc.Create(Profile{
+ pr, err := prc.CreateOrUpdate(Profile{
RBName: def.RBName,
RBVersion: def.RBVersion,
ProfileName: "default",
Namespace: "default",
ReleaseName: "default",
- })
+ }, false)
if err != nil {
logutils.Error("Create Default Profile", logutils.Fields{
@@ -139,6 +140,26 @@ func (v *DefinitionClient) Create(def Definition) (Definition, error) {
return def, nil
}
+// Update an entry for the resource in the database`
+func (v *DefinitionClient) Update(def Definition) (Definition, error) {
+
+ //Construct composite key consisting of name and version
+ key := DefinitionKey{RBName: def.RBName, RBVersion: def.RBVersion}
+
+ //Check if this definition already exists
+ _, err := v.Get(def.RBName, def.RBVersion)
+ if err != nil {
+ return Definition{}, pkgerrors.New("Definition does not exists")
+ }
+
+ err = db.DBconn.Update(v.storeName, key, v.tagMeta, def)
+ if err != nil {
+ return Definition{}, pkgerrors.Wrap(err, "Updating DB Entry")
+ }
+
+ return def, nil
+}
+
// List all resource entry's versions in the database
func (v *DefinitionClient) List(name string) ([]Definition, error) {
res, err := db.DBconn.ReadAll(v.storeName, v.tagMeta)
diff --git a/src/k8splugin/internal/rb/definition_test.go b/src/k8splugin/internal/rb/definition_test.go
index 0140b459..42fb5374 100644
--- a/src/k8splugin/internal/rb/definition_test.go
+++ b/src/k8splugin/internal/rb/definition_test.go
@@ -18,12 +18,13 @@ package rb
import (
"bytes"
- "github.com/onap/multicloud-k8s/src/k8splugin/internal/db"
"reflect"
"sort"
"strings"
"testing"
+ "github.com/onap/multicloud-k8s/src/k8splugin/internal/db"
+
pkgerrors "github.com/pkg/errors"
)
diff --git a/src/k8splugin/internal/rb/profile.go b/src/k8splugin/internal/rb/profile.go
index 78023e59..77398580 100644
--- a/src/k8splugin/internal/rb/profile.go
+++ b/src/k8splugin/internal/rb/profile.go
@@ -46,7 +46,7 @@ type Profile struct {
// ProfileManager is an interface exposes the resource bundle profile functionality
type ProfileManager interface {
- Create(def Profile) (Profile, error)
+ CreateOrUpdate(def Profile, update bool) (Profile, error)
Get(rbName, rbVersion, prName string) (Profile, error)
List(rbName, rbVersion string) ([]Profile, error)
Delete(rbName, rbVersion, prName string) error
@@ -89,8 +89,8 @@ func NewProfileClient() *ProfileClient {
}
}
-// Create an entry for the resource bundle profile in the database
-func (v *ProfileClient) Create(p Profile) (Profile, error) {
+// CreateOrUpdate an entry for the resource bundle profile in the database
+func (v *ProfileClient) CreateOrUpdate(p Profile, update bool) (Profile, error) {
// Name is required
if p.ProfileName == "" {
@@ -99,10 +99,12 @@ func (v *ProfileClient) Create(p Profile) (Profile, error) {
//Check if profile already exists
_, err := v.Get(p.RBName, p.RBVersion, p.ProfileName)
- if err == nil {
+ if err == nil && !update {
return Profile{}, pkgerrors.New("Profile already exists for this Definition")
}
-
+ if err != nil && update {
+ return Profile{}, pkgerrors.New("Profile does not exists for this Definition")
+ }
//Check if provided resource bundle information is valid
_, err = NewDefinitionClient().Get(p.RBName, p.RBVersion)
if err != nil {
@@ -120,9 +122,16 @@ func (v *ProfileClient) Create(p Profile) (Profile, error) {
ProfileName: p.ProfileName,
}
- err = db.DBconn.Create(v.storeName, key, v.tagMeta, p)
- if err != nil {
- return Profile{}, pkgerrors.Wrap(err, "Creating Profile DB Entry")
+ if update {
+ err = db.DBconn.Update(v.storeName, key, v.tagMeta, p)
+ if err != nil {
+ return Profile{}, pkgerrors.Wrap(err, "Updating Profile DB Entry")
+ }
+ } else {
+ err = db.DBconn.Create(v.storeName, key, v.tagMeta, p)
+ if err != nil {
+ return Profile{}, pkgerrors.Wrap(err, "Creating Profile DB Entry")
+ }
}
return p, nil
diff --git a/src/k8splugin/internal/rb/profile_test.go b/src/k8splugin/internal/rb/profile_test.go
index 2a9dc4fd..e52897ce 100644
--- a/src/k8splugin/internal/rb/profile_test.go
+++ b/src/k8splugin/internal/rb/profile_test.go
@@ -105,7 +105,7 @@ func TestCreateProfile(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
impl := NewProfileClient()
- got, err := impl.Create(testCase.inp)
+ got, err := impl.CreateOrUpdate(testCase.inp, false)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Create returned an unexpected error %s", err)