From dc62323aa7f6782d69c7ac6509eb270e86ef31bd Mon Sep 17 00:00:00 2001 From: Lukasz Rajewski Date: Tue, 28 Sep 2021 21:42:24 +0200 Subject: Fix for config resources delete with instance delete Issue-ID: MULTICLOUD-1332 Signed-off-by: Lukasz Rajewski Change-Id: I08a3d623d6f12777d88a168af0cb804c63104887 --- src/k8splugin/api/api.go | 5 ++- src/k8splugin/api/confighandler.go | 6 ++- src/k8splugin/api/configtemplatehandler.go | 24 ++++++++++- src/k8splugin/internal/app/config.go | 36 +++++++++------- src/k8splugin/internal/app/config_backend.go | 61 +++++++++++++++++++--------- src/k8splugin/internal/app/config_test.go | 2 +- src/k8splugin/internal/app/instance.go | 19 +++++++++ src/k8splugin/internal/db/mongo.go | 5 ++- src/k8splugin/internal/rb/config_template.go | 49 ++++++++++++++++++++-- 9 files changed, 160 insertions(+), 47 deletions(-) diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go index 94fb9b34..e34b93a2 100644 --- a/src/k8splugin/api/api.go +++ b/src/k8splugin/api/api.go @@ -123,6 +123,7 @@ func NewRouter(defClient rb.DefinitionManager, } templateHandler := rbTemplateHandler{client: templateClient} resRouter.HandleFunc("/definition/{rbname}/{rbversion}/config-template", templateHandler.createHandler).Methods("POST") + 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.deleteHandler).Methods("DELETE") @@ -137,8 +138,8 @@ func NewRouter(defClient rb.DefinitionManager, 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") - instRouter.HandleFunc("/instance/{instID}/config/rollback", configHandler.rollbackHandler).Methods("POST") - instRouter.HandleFunc("/instance/{instID}/config/tagit", configHandler.tagitHandler).Methods("POST") + instRouter.HandleFunc("/instance/{instID}/config/{cfgname}/rollback", configHandler.rollbackHandler).Methods("POST") + instRouter.HandleFunc("/instance/{instID}/config/{cfgname}/tagit", configHandler.tagitHandler).Methods("POST") // Instance Healthcheck API if healthcheckClient == nil { diff --git a/src/k8splugin/api/confighandler.go b/src/k8splugin/api/confighandler.go index c2236378..b0a8f851 100644 --- a/src/k8splugin/api/confighandler.go +++ b/src/k8splugin/api/confighandler.go @@ -176,6 +176,7 @@ func (h rbConfigHandler) updateHandler(w http.ResponseWriter, r *http.Request) { func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) instanceID := vars["instID"] + cfgName := vars["cfgname"] if r.Body == nil { http.Error(w, "Empty body", http.StatusBadRequest) @@ -188,7 +189,7 @@ func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusUnprocessableEntity) return } - err = h.client.Rollback(instanceID, p) + err = h.client.Rollback(instanceID, cfgName, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -200,6 +201,7 @@ func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request) func (h rbConfigHandler) tagitHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) instanceID := vars["instID"] + cfgName := vars["cfgname"] if r.Body == nil { http.Error(w, "Empty body", http.StatusBadRequest) @@ -213,7 +215,7 @@ func (h rbConfigHandler) tagitHandler(w http.ResponseWriter, r *http.Request) { return } - err = h.client.Tagit(instanceID, p) + err = h.client.Tagit(instanceID, cfgName, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/src/k8splugin/api/configtemplatehandler.go b/src/k8splugin/api/configtemplatehandler.go index bd7c2db9..0560c7ea 100644 --- a/src/k8splugin/api/configtemplatehandler.go +++ b/src/k8splugin/api/configtemplatehandler.go @@ -20,9 +20,10 @@ import ( "encoding/json" "io" "io/ioutil" - "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb" "net/http" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb" + "github.com/gorilla/mux" ) @@ -122,6 +123,27 @@ func (h rbTemplateHandler) getHandler(w http.ResponseWriter, r *http.Request) { } } +// getHandler handles GET operations on a particular template +func (h rbTemplateHandler) listHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + rbName := vars["rbname"] + rbVersion := vars["rbversion"] + + ret, err := h.client.List(rbName, rbVersion) + 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) diff --git a/src/k8splugin/internal/app/config.go b/src/k8splugin/internal/app/config.go index 94acadcc..a25ab543 100644 --- a/src/k8splugin/internal/app/config.go +++ b/src/k8splugin/internal/app/config.go @@ -66,8 +66,8 @@ type ConfigManager interface { Help() map[string]string Update(instanceID, configName string, p Config) (ConfigResult, error) Delete(instanceID, configName string) (ConfigResult, error) - Rollback(instanceID string, p ConfigRollback) error - Tagit(instanceID string, p ConfigTagit) error + Rollback(instanceID string, configName string, p ConfigRollback) error + Tagit(instanceID string, configName string, p ConfigTagit) error } // ConfigClient implements the ConfigManager @@ -132,6 +132,7 @@ func (v *ConfigClient) Create(instanceID string, p Config) (ConfigResult, error) // Create Version Entry in DB for Config cvs := ConfigVersionStore{ instanceID: instanceID, + configName: p.ConfigName, } version, err := cvs.createConfigVersion(p, Config{}, "POST") if err != nil { @@ -188,6 +189,7 @@ func (v *ConfigClient) Update(instanceID, configName string, p Config) (ConfigRe // Create Version Entry in DB for Config cvs := ConfigVersionStore{ instanceID: instanceID, + configName: configName, } version, err := cvs.createConfigVersion(p, configPrev, "PUT") if err != nil { @@ -277,6 +279,7 @@ func (v *ConfigClient) Delete(instanceID, configName string) (ConfigResult, erro // Create Version Entry in DB for Config cvs := ConfigVersionStore{ instanceID: instanceID, + configName: configName, } version, err := cvs.createConfigVersion(Config{}, configPrev, "DELETE") if err != nil { @@ -297,13 +300,13 @@ func (v *ConfigClient) Delete(instanceID, configName string) (ConfigResult, erro } // Rollback starts from current version and rollbacks to the version desired -func (v *ConfigClient) Rollback(instanceID string, rback ConfigRollback) error { +func (v *ConfigClient) Rollback(instanceID string, configName string, rback ConfigRollback) error { var reqVersion string var err error if rback.AnyOf.ConfigTag != "" { - reqVersion, err = v.GetTagVersion(instanceID, rback.AnyOf.ConfigTag) + reqVersion, err = v.GetTagVersion(instanceID, configName, rback.AnyOf.ConfigTag) if err != nil { return pkgerrors.Wrap(err, "Rollback Invalid tag") } @@ -326,8 +329,9 @@ func (v *ConfigClient) Rollback(instanceID string, rback ConfigRollback) error { cvs := ConfigVersionStore{ instanceID: instanceID, + configName: configName, } - currentVersion, err := cvs.getCurrentVersion() + currentVersion, err := cvs.getCurrentVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Rollback Get Current Config Version ") } @@ -338,7 +342,7 @@ func (v *ConfigClient) Rollback(instanceID string, rback ConfigRollback) error { //Rollback all the intermettinent configurations for i := currentVersion; i > rollbackIndex; i-- { - configNew, configPrev, action, err := cvs.getConfigVersion(i) + configNew, configPrev, action, err := cvs.getConfigVersion(configName, i) if err != nil { return pkgerrors.Wrap(err, "Rollback Get Config Version") } @@ -380,7 +384,7 @@ func (v *ConfigClient) Rollback(instanceID string, rback ConfigRollback) error { } for i := currentVersion; i > rollbackIndex; i-- { // Delete rolled back items - err = cvs.deleteConfigVersion() + err = cvs.deleteConfigVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Delete Config Version ") } @@ -389,7 +393,7 @@ func (v *ConfigClient) Rollback(instanceID string, rback ConfigRollback) error { } // Tagit tags the current version with the tag provided -func (v *ConfigClient) Tagit(instanceID string, tag ConfigTagit) error { +func (v *ConfigClient) Tagit(instanceID string, configName string, tag ConfigTagit) error { rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) if err != nil { @@ -402,12 +406,13 @@ func (v *ConfigClient) Tagit(instanceID string, tag ConfigTagit) error { cvs := ConfigVersionStore{ instanceID: instanceID, + configName: configName, } - currentVersion, err := cvs.getCurrentVersion() + currentVersion, err := cvs.getCurrentVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Get Current Config Version ") } - tagKey := constructKey(rbName, rbVersion, profileName, instanceID, v.tagTag, tag.TagName) + tagKey := constructKey(rbName, rbVersion, profileName, instanceID, v.tagTag, configName, tag.TagName) err = db.Etcd.Put(tagKey, strconv.Itoa(int(currentVersion))) if err != nil { @@ -417,13 +422,13 @@ func (v *ConfigClient) Tagit(instanceID string, tag ConfigTagit) error { } // GetTagVersion returns the version associated with the tag -func (v *ConfigClient) GetTagVersion(instanceID, tagName string) (string, error) { +func (v *ConfigClient) GetTagVersion(instanceID, configName string, tagName string) (string, error) { rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) if err != nil { return "", pkgerrors.Wrap(err, "Retrieving model info") } - tagKey := constructKey(rbName, rbVersion, profileName, instanceID, v.tagTag, tagName) + tagKey := constructKey(rbName, rbVersion, profileName, instanceID, v.tagTag, configName, tagName) value, err := db.Etcd.Get(tagKey) if err != nil { @@ -433,7 +438,7 @@ func (v *ConfigClient) GetTagVersion(instanceID, tagName string) (string, error) } // ApplyAllConfig starts from first configuration version and applies all versions in sequence -func (v *ConfigClient) ApplyAllConfig(instanceID string) error { +func (v *ConfigClient) ApplyAllConfig(instanceID string, configName string) error { lock, profileChannel := getProfileData(instanceID) // Acquire per profile Mutex @@ -442,8 +447,9 @@ func (v *ConfigClient) ApplyAllConfig(instanceID string) error { cvs := ConfigVersionStore{ instanceID: instanceID, + configName: configName, } - currentVersion, err := cvs.getCurrentVersion() + currentVersion, err := cvs.getCurrentVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Get Current Config Version ") } @@ -453,7 +459,7 @@ func (v *ConfigClient) ApplyAllConfig(instanceID string) error { //Apply all configurations var i uint for i = 1; i <= currentVersion; i++ { - configNew, _, action, err := cvs.getConfigVersion(i) + configNew, _, action, err := cvs.getConfigVersion(configName, i) if err != nil { return pkgerrors.Wrap(err, "Get Config Version") } diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go index 30a480df..3e5d8a3f 100644 --- a/src/k8splugin/internal/app/config_backend.go +++ b/src/k8splugin/internal/app/config_backend.go @@ -52,6 +52,7 @@ type ConfigStore struct { //ConfigVersionStore to Store the Versions of the Config type ConfigVersionStore struct { instanceID string + configName string } type configResourceList struct { @@ -225,7 +226,14 @@ func (c ConfigStore) deleteConfig() (Config, error) { // Create a version for the configuration. If previous config provided that is also stored func (c ConfigVersionStore) createConfigVersion(configNew, configPrev Config, action string) (uint, error) { - version, err := c.incrementVersion() + configName := "" + if configNew.ConfigName != "" { + configName = configNew.ConfigName + } else { + configName = configPrev.ConfigName + } + + version, err := c.incrementVersion(configName) if err != nil { return 0, pkgerrors.Wrap(err, "Get Next Version") @@ -234,7 +242,8 @@ func (c ConfigVersionStore) createConfigVersion(configNew, configPrev Config, ac if err != nil { return 0, pkgerrors.Wrap(err, "Retrieving model info") } - versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, strconv.Itoa(int(version))) + + versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, configName, strconv.Itoa(int(version))) var cs configVersionDBContent cs.Action = action @@ -253,9 +262,9 @@ func (c ConfigVersionStore) createConfigVersion(configNew, configPrev Config, ac } // Delete current version of the configuration. Configuration always deleted from top -func (c ConfigVersionStore) deleteConfigVersion() error { +func (c ConfigVersionStore) deleteConfigVersion(configName string) error { - counter, err := c.getCurrentVersion() + counter, err := c.getCurrentVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Get Next Version") @@ -264,13 +273,13 @@ func (c ConfigVersionStore) deleteConfigVersion() error { if err != nil { return pkgerrors.Wrap(err, "Retrieving model info") } - versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, strconv.Itoa(int(counter))) + versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, configName, strconv.Itoa(int(counter))) err = db.Etcd.Delete(versionKey) if err != nil { return pkgerrors.Wrap(err, "Delete Config DB Entry") } - err = c.decrementVersion() + err = c.decrementVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Decrement Version") } @@ -279,13 +288,13 @@ func (c ConfigVersionStore) deleteConfigVersion() error { // Read the specified version of the configuration and return its prev and current value. // Also returns the action for the config version -func (c ConfigVersionStore) getConfigVersion(version uint) (Config, Config, string, error) { +func (c ConfigVersionStore) getConfigVersion(configName string, version uint) (Config, Config, string, error) { rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID) if err != nil { return Config{}, Config{}, "", pkgerrors.Wrap(err, "Retrieving model info") } - versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, strconv.Itoa(int(version))) + versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, configName, strconv.Itoa(int(version))) configBytes, err := db.Etcd.Get(versionKey) if err != nil { return Config{}, Config{}, "", pkgerrors.Wrap(err, "Get Config Version ") @@ -303,13 +312,13 @@ func (c ConfigVersionStore) getConfigVersion(version uint) (Config, Config, stri } // Get the counter for the version -func (c ConfigVersionStore) getCurrentVersion() (uint, error) { +func (c ConfigVersionStore) getCurrentVersion(configName string) (uint, error) { rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID) if err != nil { return 0, pkgerrors.Wrap(err, "Retrieving model info") } - cfgKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagCounter) + cfgKey := constructKey(rbName, rbVersion, profileName, c.instanceID, configName, tagCounter) value, err := db.Etcd.Get(cfgKey) if err != nil { @@ -329,13 +338,13 @@ func (c ConfigVersionStore) getCurrentVersion() (uint, error) { } // Update the counter for the version -func (c ConfigVersionStore) updateVersion(counter uint) error { +func (c ConfigVersionStore) updateVersion(configName string, counter uint) error { rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID) if err != nil { return pkgerrors.Wrap(err, "Retrieving model info") } - cfgKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagCounter) + cfgKey := constructKey(rbName, rbVersion, profileName, c.instanceID, configName, tagCounter) err = db.Etcd.Put(cfgKey, strconv.Itoa(int(counter))) if err != nil { return pkgerrors.Wrap(err, "Counter DB Entry") @@ -344,15 +353,15 @@ func (c ConfigVersionStore) updateVersion(counter uint) error { } // Increment the version counter -func (c ConfigVersionStore) incrementVersion() (uint, error) { +func (c ConfigVersionStore) incrementVersion(configName string) (uint, error) { - counter, err := c.getCurrentVersion() + counter, err := c.getCurrentVersion(configName) if err != nil { return 0, pkgerrors.Wrap(err, "Get Next Counter Value") } //This is done while Profile lock is taken counter++ - err = c.updateVersion(counter) + err = c.updateVersion(configName, counter) if err != nil { return 0, pkgerrors.Wrap(err, "Store Next Counter Value") } @@ -361,15 +370,15 @@ func (c ConfigVersionStore) incrementVersion() (uint, error) { } // Decrement the version counter -func (c ConfigVersionStore) decrementVersion() error { +func (c ConfigVersionStore) decrementVersion(configName string) error { - counter, err := c.getCurrentVersion() + counter, err := c.getCurrentVersion(configName) if err != nil { return pkgerrors.Wrap(err, "Get Next Counter Value") } //This is done while Profile lock is taken counter-- - err = c.updateVersion(counter) + err = c.updateVersion(configName, counter) if err != nil { return pkgerrors.Wrap(err, "Store Next Counter Value") } @@ -437,10 +446,22 @@ func scheduleResources(c chan configResourceList) { } } } - //TODO: Needs to add code to call Kubectl create case data.action == "PUT": log.Printf("[scheduleResources]: PUT %v %v", data.profile, data.resourceTemplates) - //TODO: Needs to add code to call Kubectl apply + for _, inst := range resp { + k8sClient := KubernetesClient{} + err = k8sClient.Init(inst.Request.CloudRegion, inst.ID) + if err != nil { + log.Printf("Getting CloudRegion Information: %s", err.Error()) + //Move onto the next cloud region + continue + } + data.createdResources, err = k8sClient.updateResources(data.resourceTemplates, inst.Namespace) + if err != nil { + log.Printf("Error Updating resources: %s", err.Error()) + continue + } + } case data.action == "DELETE": log.Printf("[scheduleResources]: DELETE %v %v", data.profile, data.resourceTemplates) for _, inst := range resp { diff --git a/src/k8splugin/internal/app/config_test.go b/src/k8splugin/internal/app/config_test.go index 9ee96881..dc4779d8 100644 --- a/src/k8splugin/internal/app/config_test.go +++ b/src/k8splugin/internal/app/config_test.go @@ -293,7 +293,7 @@ func TestRollbackConfig(t *testing.T) { } } testCase.rollbackConfig.AnyOf.ConfigVersion = "2" - err = impl.Rollback(testCase.instanceID, testCase.rollbackConfig) + err = impl.Rollback(testCase.instanceID, testCase.inp.ConfigName, testCase.rollbackConfig) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index ad36aaa5..0f1f3d7e 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -717,6 +717,13 @@ func (v *InstanceClient) Delete(id string) error { if err != nil { return pkgerrors.Wrap(err, "Getting CloudRegion Information") } + + configClient := NewConfigClient() + configs, err := configClient.List(id) + if err != nil { + return pkgerrors.Wrap(err, "Getting Configs Information") + } + inst.Status = "PRE-DELETE" inst.HookProgress = "" err = db.DBconn.Update(v.storeName, key, v.tagInst, inst) @@ -743,6 +750,18 @@ func (v *InstanceClient) Delete(id string) error { if err != nil { log.Printf("Update Instance DB Entry for release %s has error.", inst.ReleaseName) } + + if len(configs) > 0 { + log.Printf("Deleting config resources first") + for _, config := range configs { + log.Printf("Deleting Config %s Resources", config.ConfigName) + _, err = configClient.Delete(id, config.ConfigName) + if err != nil { + return pkgerrors.Wrap(err, "Deleting Config Resources") + } + } + } + err = k8sClient.deleteResources(inst.Resources, inst.Namespace) if err != nil { return pkgerrors.Wrap(err, "Deleting Instance Resources") diff --git a/src/k8splugin/internal/db/mongo.go b/src/k8splugin/internal/db/mongo.go index c15b108b..aa05820a 100644 --- a/src/k8splugin/internal/db/mongo.go +++ b/src/k8splugin/internal/db/mongo.go @@ -17,9 +17,10 @@ package db import ( - "golang.org/x/net/context" "log" + "golang.org/x/net/context" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/config" pkgerrors "github.com/pkg/errors" @@ -374,7 +375,7 @@ func (m *MongoStore) ReadAll(coll, tag string) (map[string][]byte, error) { //Get objectID of tag document tid, ok := d.Lookup(tag).ObjectIDOK() if !ok { - log.Printf("Did not find tag: %s", tag) + //"Did not find tag: %s", tag) continue } diff --git a/src/k8splugin/internal/rb/config_template.go b/src/k8splugin/internal/rb/config_template.go index cf45a6f2..b84b6461 100644 --- a/src/k8splugin/internal/rb/config_template.go +++ b/src/k8splugin/internal/rb/config_template.go @@ -20,14 +20,16 @@ import ( "bytes" "encoding/json" "io/ioutil" - "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" "os" "path/filepath" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" + "encoding/base64" - pkgerrors "github.com/pkg/errors" "log" + + pkgerrors "github.com/pkg/errors" ) // ConfigTemplate contains the parameters needed for ConfigTemplates @@ -41,6 +43,7 @@ type ConfigTemplate struct { type ConfigTemplateManager interface { Create(rbName, rbVersion string, p ConfigTemplate) error Get(rbName, rbVersion, templateName string) (ConfigTemplate, error) + List(rbName, rbVersion string) ([]ConfigTemplate, error) Delete(rbName, rbVersion, templateName string) error Upload(rbName, rbVersion, templateName string, inp []byte) error } @@ -76,8 +79,8 @@ type ConfigTemplateClient struct { func NewConfigTemplateClient() *ConfigTemplateClient { return &ConfigTemplateClient{ storeName: "rbdef", - tagMeta: "metadata", - tagContent: "content", + tagMeta: "confdefmetadata", + tagContent: "confdefcontent", } } @@ -141,6 +144,44 @@ func (v *ConfigTemplateClient) Get(rbName, rbVersion, templateName string) (Conf return ConfigTemplate{}, pkgerrors.New("Error getting ConfigTemplate") } +// List returns the Resource Bundle ConfigTemplate for corresponding ID +func (v *ConfigTemplateClient) List(rbName, rbVersion string) ([]ConfigTemplate, error) { + + //Get all config templates + dbres, err := db.DBconn.ReadAll(v.storeName, v.tagMeta) + if err != nil || len(dbres) == 0 { + return []ConfigTemplate{}, pkgerrors.Wrap(err, "No Config Templates Found") + } + + var results []ConfigTemplate + for key, value := range dbres { + //value is a byte array + if value != nil { + tmp := ConfigTemplate{} + err = db.DBconn.Unmarshal(value, &tmp) + if err != nil { + log.Printf("[ConfigTemplate] Error: %s Unmarshaling value for: %s", err.Error(), key) + continue + } + keyTmp := ConfigTemplateKey{ + RBName: rbName, + RBVersion: rbVersion, + TemplateName: tmp.TemplateName, + } + _, err := db.DBconn.Read(v.storeName, keyTmp, v.tagMeta) + if err == nil && keyTmp.RBName == rbName && keyTmp.RBVersion == rbVersion { + results = append(results, tmp) + } + } + } + + if len(results) == 0 { + return results, pkgerrors.New("No Config Templates Found for Definition and Version") + } + + return results, nil +} + // Delete the Resource Bundle ConfigTemplate from database func (v *ConfigTemplateClient) Delete(rbName, rbVersion, templateName string) error { key := ConfigTemplateKey{ -- cgit 1.2.3-korg