aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Rajewski <lukasz.rajewski@orange.com>2021-08-02 22:15:35 +0200
committerLukasz Rajewski <lukasz.rajewski@orange.com>2021-08-02 22:30:16 +0200
commit91fe5c50c2d882a5c831dd473d8db765b2dd8699 (patch)
treea2c42ea34ea265b7ef72c237ece1c19b231be8c4
parente42203ee6c170eebb9466ee82baa97f83e88955c (diff)
Config List handler added to Config API
Config List handler added to Config API Issue-ID: MULTICLOUD-1332 Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com> Change-Id: I63355dd6b05e70398cfc89744efa332926286c40
-rw-r--r--src/k8splugin/api/api.go1
-rw-r--r--src/k8splugin/api/confighandler.go21
-rw-r--r--src/k8splugin/internal/app/config.go21
-rw-r--r--src/k8splugin/internal/app/config_backend.go27
-rw-r--r--src/k8splugin/internal/app/config_test.go38
-rw-r--r--src/k8splugin/internal/db/etcd.go19
-rw-r--r--src/k8splugin/internal/db/etcd_testing.go12
7 files changed, 132 insertions, 7 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go
index 4a196ae2..1c7c5eaf 100644
--- a/src/k8splugin/api/api.go
+++ b/src/k8splugin/api/api.go
@@ -116,6 +116,7 @@ func NewRouter(defClient rb.DefinitionManager,
}
configHandler := rbConfigHandler{client: configClient}
instRouter.HandleFunc("/instance/{instID}/config", configHandler.createHandler).Methods("POST")
+ instRouter.HandleFunc("/instance/{instID}/config", configHandler.listHandler).Methods("GET")
instRouter.HandleFunc("/instance/{instID}/config/{cfgname}", configHandler.getHandler).Methods("GET")
instRouter.HandleFunc("/instance/{instID}/config/{cfgname}", configHandler.updateHandler).Methods("PUT")
instRouter.HandleFunc("/instance/{instID}/config/{cfgname}", configHandler.deleteHandler).Methods("DELETE")
diff --git a/src/k8splugin/api/confighandler.go b/src/k8splugin/api/confighandler.go
index f4bb0862..4ce30799 100644
--- a/src/k8splugin/api/confighandler.go
+++ b/src/k8splugin/api/confighandler.go
@@ -94,6 +94,27 @@ func (h rbConfigHandler) getHandler(w http.ResponseWriter, r *http.Request) {
}
}
+// listHandler handles GET operations for all configs of instance
+// Returns a app.Definition
+func (h rbConfigHandler) listHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ instanceID := vars["instID"]
+
+ ret, err := h.client.List(instanceID)
+ 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)
diff --git a/src/k8splugin/internal/app/config.go b/src/k8splugin/internal/app/config.go
index d0f8876d..94acadcc 100644
--- a/src/k8splugin/internal/app/config.go
+++ b/src/k8splugin/internal/app/config.go
@@ -42,7 +42,7 @@ type ConfigResult struct {
ProfileName string `json:"profile-name"`
ConfigName string `json:"config-name"`
TemplateName string `json:"template-name"`
- ConfigVersion uint `json:"config-verion"`
+ ConfigVersion uint `json:"config-version"`
}
//ConfigRollback input
@@ -62,6 +62,7 @@ type ConfigTagit struct {
type ConfigManager interface {
Create(instanceID string, p Config) (ConfigResult, error)
Get(instanceID, configName string) (Config, error)
+ List(instanceID string) ([]Config, error)
Help() map[string]string
Update(instanceID, configName string, p Config) (ConfigResult, error)
Delete(instanceID, configName string) (ConfigResult, error)
@@ -225,6 +226,24 @@ func (v *ConfigClient) Get(instanceID, configName string) (Config, error) {
return cfg, nil
}
+// List config entry in the database
+func (v *ConfigClient) List(instanceID string) ([]Config, error) {
+
+ // Acquire per profile Mutex
+ lock, _ := getProfileData(instanceID)
+ lock.Lock()
+ defer lock.Unlock()
+ // Read Config DB
+ cs := ConfigStore{
+ instanceID: instanceID,
+ }
+ cfg, err := cs.getConfigList()
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Get Config DB Entry")
+ }
+ return cfg, nil
+}
+
// Delete the Config from database
func (v *ConfigClient) Delete(instanceID, configName string) (ConfigResult, error) {
diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go
index 8187960f..30a480df 100644
--- a/src/k8splugin/internal/app/config_backend.go
+++ b/src/k8splugin/internal/app/config_backend.go
@@ -170,6 +170,33 @@ func (c ConfigStore) getConfig() (Config, error) {
return Config{}, pkgerrors.Wrap(err, "Get Config DB Entry")
}
+// Read the config entry in the database
+func (c ConfigStore) getConfigList() ([]Config, error) {
+ rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID)
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Retrieving model info")
+ }
+ cfgKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagConfig)
+ values, err := db.Etcd.GetAll(cfgKey)
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Get Config DB List")
+ }
+ //value is a byte array
+ if values != nil {
+ result := make([]Config, 0)
+ for _, value := range values {
+ cfg := Config{}
+ err = db.DeSerialize(string(value), &cfg)
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Unmarshaling Config Value")
+ }
+ result = append(result, cfg)
+ }
+ return result, nil
+ }
+ return []Config{}, pkgerrors.Wrap(err, "Get Config DB List")
+}
+
// Delete the config entry in the database
func (c ConfigStore) deleteConfig() (Config, error) {
diff --git a/src/k8splugin/internal/app/config_test.go b/src/k8splugin/internal/app/config_test.go
index f20ef055..9ee96881 100644
--- a/src/k8splugin/internal/app/config_test.go
+++ b/src/k8splugin/internal/app/config_test.go
@@ -105,7 +105,7 @@ func TestCreateConfig(t *testing.T) {
}
} else {
if reflect.DeepEqual(testCase.expected, got) == false {
- t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
+ t.Errorf("Create returned unexpected body: got %v;"+
" expected %v", got, testCase.expected)
}
}
@@ -218,10 +218,38 @@ func TestRollbackConfig(t *testing.T) {
}
} else {
if reflect.DeepEqual(testCase.expected1, got) == false {
- t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
+ t.Errorf("Create returned unexpected body: got %v;"+
" expected %v", got, testCase.expected1)
}
}
+ get, err := impl.Get(testCase.instanceID, testCase.inp.ConfigName)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Get returned an unexpected error %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("Get returned an unexpected error %s", err)
+ }
+ } else {
+ if reflect.DeepEqual(testCase.inp, get) == false {
+ t.Errorf("Get returned unexpected body: got %v;"+
+ " expected %v", get, testCase.inp)
+ }
+ }
+ getList, err := impl.List(testCase.instanceID)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("List returned an unexpected error %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("List returned an unexpected error %s", err)
+ }
+ } else {
+ if reflect.DeepEqual([]Config{testCase.inp}, getList) == false {
+ t.Errorf("List returned unexpected body: got %v;"+
+ " expected %v", getList, []Config{testCase.inp})
+ }
+ }
got, err = impl.Update(testCase.instanceID, testCase.inp.ConfigName, testCase.inpUpdate1)
if err != nil {
if testCase.expectedError == "" {
@@ -232,7 +260,7 @@ func TestRollbackConfig(t *testing.T) {
}
} else {
if reflect.DeepEqual(testCase.expected2, got) == false {
- t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
+ t.Errorf("Create returned unexpected body: got %v;"+
" expected %v", got, testCase.expected2)
}
}
@@ -246,7 +274,7 @@ func TestRollbackConfig(t *testing.T) {
}
} else {
if reflect.DeepEqual(testCase.expected3, got) == false {
- t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
+ t.Errorf("Create returned unexpected body: got %v;"+
" expected %v", got, testCase.expected3)
}
}
@@ -260,7 +288,7 @@ func TestRollbackConfig(t *testing.T) {
}
} else {
if reflect.DeepEqual(testCase.expected4, got) == false {
- t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+
+ t.Errorf("Create returned unexpected body: got %v;"+
" expected %v", got, testCase.expected4)
}
}
diff --git a/src/k8splugin/internal/db/etcd.go b/src/k8splugin/internal/db/etcd.go
index 97771a07..a435b435 100644
--- a/src/k8splugin/internal/db/etcd.go
+++ b/src/k8splugin/internal/db/etcd.go
@@ -36,6 +36,7 @@ type EtcdConfig struct {
// EtcdStore Interface needed for mocking
type EtcdStore interface {
Get(key string) ([]byte, error)
+ GetAll(key string) ([][]byte, error)
Put(key, value string) error
Delete(key string) error
}
@@ -114,7 +115,7 @@ func (e EtcdClient) Get(key string) ([]byte, error) {
}
getResp, err := e.cli.Get(context.Background(), key)
if err != nil {
- return nil, pkgerrors.Errorf("Error getitng etcd entry: %s", err.Error())
+ return nil, pkgerrors.Errorf("Error getting etcd entry: %s", err.Error())
}
if getResp.Count == 0 {
return nil, pkgerrors.Errorf("Key doesn't exist")
@@ -122,6 +123,22 @@ func (e EtcdClient) Get(key string) ([]byte, error) {
return getResp.Kvs[0].Value, nil
}
+// GetAll sub values from Etcd DB
+func (e EtcdClient) GetAll(key string) ([][]byte, error) {
+ if e.cli == nil {
+ return nil, pkgerrors.Errorf("Etcd Client not initialized")
+ }
+ getResp, err := e.cli.Get(context.Background(), key, clientv3.WithPrefix())
+ if err != nil {
+ return nil, pkgerrors.Errorf("Error getting etcd entry: %s", err.Error())
+ }
+ result := make([][]byte, 0)
+ for _, v := range getResp.Kvs {
+ result = append(result, v.Value)
+ }
+ return result, nil
+}
+
// Delete values from Etcd DB
func (e EtcdClient) Delete(key string) error {
diff --git a/src/k8splugin/internal/db/etcd_testing.go b/src/k8splugin/internal/db/etcd_testing.go
index 12b17e33..9dfcad82 100644
--- a/src/k8splugin/internal/db/etcd_testing.go
+++ b/src/k8splugin/internal/db/etcd_testing.go
@@ -14,6 +14,8 @@ limitations under the License.
package db
import (
+ "strings"
+
pkgerrors "github.com/pkg/errors"
)
@@ -39,6 +41,16 @@ func (c *MockEtcdClient) Get(key string) ([]byte, error) {
return nil, pkgerrors.Errorf("Key doesn't exist")
}
+func (c *MockEtcdClient) GetAll(key string) ([][]byte, error) {
+ result := make([][]byte, 0)
+ for kvKey, kvValue := range c.Items {
+ if strings.HasPrefix(kvKey, key) {
+ result = append(result, []byte(kvValue))
+ }
+ }
+ return result, nil
+}
+
func (c *MockEtcdClient) Delete(key string) error {
delete(c.Items, key)
return c.Err