From f026b794a6be909731470af5398b03af375e7b78 Mon Sep 17 00:00:00 2001 From: Konrad Bańka Date: Tue, 23 Feb 2021 20:35:59 +0100 Subject: Move Day2 Config Values API to new endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue-ID: MULTICLOUD-1280 Signed-off-by: Konrad Bańka Change-Id: Ibeb0920b4ce083f4294b83c887fc7c793a2c3df5 --- src/k8splugin/api/api.go | 13 +-- src/k8splugin/api/confighandler.go | 37 +++---- src/k8splugin/internal/app/config.go | 153 ++++++++++++++------------- src/k8splugin/internal/app/config_backend.go | 81 ++++++++++---- src/k8splugin/internal/app/config_test.go | 47 ++++++-- src/k8splugin/internal/app/instance.go | 12 ++- 6 files changed, 211 insertions(+), 132 deletions(-) diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go index c836fc65..cb094683 100644 --- a/src/k8splugin/api/api.go +++ b/src/k8splugin/api/api.go @@ -1,5 +1,6 @@ /* Copyright 2018 Intel Corporation. +Copyright © 2021 Samsung Electronics 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 @@ -107,12 +108,12 @@ func NewRouter(defClient rb.DefinitionManager, configClient = app.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") + instRouter.HandleFunc("/instance/{instID}/config", configHandler.createHandler).Methods("POST") + 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") // Add healthcheck path instRouter.HandleFunc("/healthcheck", healthCheckHandler).Methods("GET") diff --git a/src/k8splugin/api/confighandler.go b/src/k8splugin/api/confighandler.go index c9af2893..f4bb0862 100644 --- a/src/k8splugin/api/confighandler.go +++ b/src/k8splugin/api/confighandler.go @@ -1,5 +1,6 @@ /* * Copyright 2018 Intel Corporation, Inc + * Copyright © 2021 Samsung Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,9 +38,7 @@ type rbConfigHandler struct { func (h rbConfigHandler) createHandler(w http.ResponseWriter, r *http.Request) { var p app.Config vars := mux.Vars(r) - rbName := vars["rbname"] - rbVersion := vars["rbversion"] - prName := vars["prname"] + instanceID := vars["instID"] if r.Body == nil { http.Error(w, "Empty body", http.StatusBadRequest) @@ -58,7 +57,7 @@ func (h rbConfigHandler) createHandler(w http.ResponseWriter, r *http.Request) { return } - ret, err := h.client.Create(rbName, rbVersion, prName, p) + ret, err := h.client.Create(instanceID, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -77,12 +76,10 @@ func (h rbConfigHandler) createHandler(w http.ResponseWriter, r *http.Request) { // Returns a app.Definition func (h rbConfigHandler) getHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - rbName := vars["rbname"] - rbVersion := vars["rbversion"] - prName := vars["prname"] + instanceID := vars["instID"] cfgName := vars["cfgname"] - ret, err := h.client.Get(rbName, rbVersion, prName, cfgName) + ret, err := h.client.Get(instanceID, cfgName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -100,12 +97,10 @@ func (h rbConfigHandler) getHandler(w http.ResponseWriter, r *http.Request) { // 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"] + instanceID := vars["instID"] cfgName := vars["cfgname"] - ret, err := h.client.Delete(rbName, rbVersion, prName, cfgName) + ret, err := h.client.Delete(instanceID, cfgName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -124,9 +119,7 @@ func (h rbConfigHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { // 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"] + instanceID := vars["instID"] cfgName := vars["cfgname"] var p app.Config @@ -142,7 +135,7 @@ func (h rbConfigHandler) updateHandler(w http.ResponseWriter, r *http.Request) { return } - ret, err := h.client.Update(rbName, rbVersion, prName, cfgName, p) + ret, err := h.client.Update(instanceID, cfgName, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -160,9 +153,7 @@ func (h rbConfigHandler) updateHandler(w http.ResponseWriter, r *http.Request) { // 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"] + instanceID := vars["instID"] if r.Body == nil { http.Error(w, "Empty body", http.StatusBadRequest) @@ -175,7 +166,7 @@ func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusUnprocessableEntity) return } - err = h.client.Rollback(rbName, rbVersion, prName, p) + err = h.client.Rollback(instanceID, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -186,9 +177,7 @@ func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request) // 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"] + instanceID := vars["instID"] if r.Body == nil { http.Error(w, "Empty body", http.StatusBadRequest) @@ -202,7 +191,7 @@ func (h rbConfigHandler) tagitHandler(w http.ResponseWriter, r *http.Request) { return } - err = h.client.Tagit(rbName, rbVersion, prName, p) + err = h.client.Tagit(instanceID, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/src/k8splugin/internal/app/config.go b/src/k8splugin/internal/app/config.go index 10bd179d..d0f8876d 100644 --- a/src/k8splugin/internal/app/config.go +++ b/src/k8splugin/internal/app/config.go @@ -1,5 +1,6 @@ /* * Copyright 2018 Intel Corporation, Inc + * Copyright © 2021 Samsung Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +36,7 @@ type Config struct { //ConfigResult output for Create, Update and delete type ConfigResult struct { + InstanceName string `json:"instance-id"` DefinitionName string `json:"rb-name"` DefinitionVersion string `json:"rb-version"` ProfileName string `json:"profile-name"` @@ -58,13 +60,13 @@ type ConfigTagit struct { // ConfigManager is an interface exposes the config functionality type ConfigManager interface { - Create(rbName, rbVersion, profileName string, p Config) (ConfigResult, error) - Get(rbName, rbVersion, profileName, configName string) (Config, error) + Create(instanceID string, p Config) (ConfigResult, error) + Get(instanceID, configName string) (Config, error) Help() map[string]string - Update(rbName, rbVersion, profileName, configName string, p Config) (ConfigResult, error) - Delete(rbName, rbVersion, profileName, configName string) (ConfigResult, error) - Rollback(rbName, rbVersion, profileName string, p ConfigRollback) error - Tagit(rbName, rbVersion, profileName string, p ConfigTagit) error + 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 } // ConfigClient implements the ConfigManager @@ -90,19 +92,22 @@ func (v *ConfigClient) Help() map[string]string { } // Create an entry for the config in the database -func (v *ConfigClient) Create(rbName, rbVersion, profileName string, p Config) (ConfigResult, error) { +func (v *ConfigClient) Create(instanceID string, p Config) (ConfigResult, error) { // Check required fields if p.ConfigName == "" || p.TemplateName == "" || len(p.Values) == 0 { return ConfigResult{}, pkgerrors.New("Incomplete Configuration Provided") } + // Resolving rbName, Version, etc. not to break response + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) + if err != nil { + return ConfigResult{}, pkgerrors.Wrap(err, "Retrieving model info") + } cs := ConfigStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, - configName: p.ConfigName, + instanceID: instanceID, + configName: p.ConfigName, } - _, err := cs.getConfig() + _, err = cs.getConfig() if err == nil { return ConfigResult{}, pkgerrors.Wrap(err, "Create Error - Config exists") } else { @@ -110,13 +115,13 @@ func (v *ConfigClient) Create(rbName, rbVersion, profileName string, p Config) ( return ConfigResult{}, pkgerrors.Wrap(err, "Create Error") } } - lock, profileChannel := getProfileData(rbName + rbVersion + profileName) + lock, profileChannel := getProfileData(instanceID) // Acquire per profile Mutex lock.Lock() defer lock.Unlock() - err = applyConfig(rbName, rbVersion, profileName, p, profileChannel, "POST") + err = applyConfig(instanceID, p, profileChannel, "POST") if err != nil { - return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed") + return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed") } // Create Config DB Entry err = cs.createConfig(p) @@ -125,16 +130,16 @@ func (v *ConfigClient) Create(rbName, rbVersion, profileName string, p Config) ( } // Create Version Entry in DB for Config cvs := ConfigVersionStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, + instanceID: instanceID, } version, err := cvs.createConfigVersion(p, Config{}, "POST") if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Create Config Version DB Entry") } + // Create Result structure cfgRes := ConfigResult{ + InstanceName: instanceID, DefinitionName: rbName, DefinitionVersion: rbVersion, ProfileName: profileName, @@ -146,28 +151,31 @@ func (v *ConfigClient) Create(rbName, rbVersion, profileName string, p Config) ( } // Update an entry for the config in the database -func (v *ConfigClient) Update(rbName, rbVersion, profileName, configName string, p Config) (ConfigResult, error) { +func (v *ConfigClient) Update(instanceID, configName string, p Config) (ConfigResult, error) { // Check required fields if len(p.Values) == 0 { return ConfigResult{}, pkgerrors.New("Incomplete Configuration Provided") } + // Resolving rbName, Version, etc. not to break response + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) + if err != nil { + return ConfigResult{}, pkgerrors.Wrap(err, "Retrieving model info") + } // Check if Config exists cs := ConfigStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, - configName: configName, + instanceID: instanceID, + configName: configName, } - _, err := cs.getConfig() + _, err = cs.getConfig() if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Update Error - Config doesn't exist") } - lock, profileChannel := getProfileData(rbName + rbVersion + profileName) + lock, profileChannel := getProfileData(instanceID) // Acquire per profile Mutex lock.Lock() defer lock.Unlock() - err = applyConfig(rbName, rbVersion, profileName, p, profileChannel, "PUT") + err = applyConfig(instanceID, p, profileChannel, "PUT") if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed") } @@ -178,16 +186,16 @@ func (v *ConfigClient) Update(rbName, rbVersion, profileName, configName string, } // Create Version Entry in DB for Config cvs := ConfigVersionStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, + instanceID: instanceID, } version, err := cvs.createConfigVersion(p, configPrev, "PUT") if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Create Config Version DB Entry") } + // Create Result structure cfgRes := ConfigResult{ + InstanceName: instanceID, DefinitionName: rbName, DefinitionVersion: rbVersion, ProfileName: profileName, @@ -199,18 +207,16 @@ func (v *ConfigClient) Update(rbName, rbVersion, profileName, configName string, } // Get config entry in the database -func (v *ConfigClient) Get(rbName, rbVersion, profileName, configName string) (Config, error) { +func (v *ConfigClient) Get(instanceID, configName string) (Config, error) { // Acquire per profile Mutex - lock, _ := getProfileData(rbName + rbVersion + profileName) + lock, _ := getProfileData(instanceID) lock.Lock() defer lock.Unlock() // Read Config DB cs := ConfigStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, - configName: configName, + instanceID: instanceID, + configName: configName, } cfg, err := cs.getConfig() if err != nil { @@ -220,24 +226,27 @@ func (v *ConfigClient) Get(rbName, rbVersion, profileName, configName string) (C } // Delete the Config from database -func (v *ConfigClient) Delete(rbName, rbVersion, profileName, configName string) (ConfigResult, error) { +func (v *ConfigClient) Delete(instanceID, configName string) (ConfigResult, error) { + // Resolving rbName, Version, etc. not to break response + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) + if err != nil { + return ConfigResult{}, pkgerrors.Wrap(err, "Retrieving model info") + } // Check if Config exists cs := ConfigStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, - configName: configName, + instanceID: instanceID, + configName: configName, } p, err := cs.getConfig() if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Update Error - Config doesn't exist") } - lock, profileChannel := getProfileData(rbName + rbVersion + profileName) + lock, profileChannel := getProfileData(instanceID) // Acquire per profile Mutex lock.Lock() defer lock.Unlock() - err = applyConfig(rbName, rbVersion, profileName, p, profileChannel, "DELETE") + err = applyConfig(instanceID, p, profileChannel, "DELETE") if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed") } @@ -248,16 +257,16 @@ func (v *ConfigClient) Delete(rbName, rbVersion, profileName, configName string) } // Create Version Entry in DB for Config cvs := ConfigVersionStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, + instanceID: instanceID, } version, err := cvs.createConfigVersion(Config{}, configPrev, "DELETE") if err != nil { return ConfigResult{}, pkgerrors.Wrap(err, "Delete Config Version DB Entry") } + // Create Result structure cfgRes := ConfigResult{ + InstanceName: instanceID, DefinitionName: rbName, DefinitionVersion: rbVersion, ProfileName: profileName, @@ -269,13 +278,13 @@ func (v *ConfigClient) Delete(rbName, rbVersion, profileName, configName string) } // Rollback starts from current version and rollbacks to the version desired -func (v *ConfigClient) Rollback(rbName, rbVersion, profileName string, rback ConfigRollback) error { +func (v *ConfigClient) Rollback(instanceID string, rback ConfigRollback) error { var reqVersion string var err error if rback.AnyOf.ConfigTag != "" { - reqVersion, err = v.GetTagVersion(rbName, rbVersion, profileName, rback.AnyOf.ConfigTag) + reqVersion, err = v.GetTagVersion(instanceID, rback.AnyOf.ConfigTag) if err != nil { return pkgerrors.Wrap(err, "Rollback Invalid tag") } @@ -291,15 +300,13 @@ func (v *ConfigClient) Rollback(rbName, rbVersion, profileName string, rback Con } rollbackIndex := uint(index) - lock, profileChannel := getProfileData(rbName + rbVersion + profileName) + lock, profileChannel := getProfileData(instanceID) // Acquire per profile Mutex lock.Lock() defer lock.Unlock() cvs := ConfigVersionStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, + instanceID: instanceID, } currentVersion, err := cvs.getCurrentVersion() if err != nil { @@ -317,14 +324,12 @@ func (v *ConfigClient) Rollback(rbName, rbVersion, profileName string, rback Con return pkgerrors.Wrap(err, "Rollback Get Config Version") } cs := ConfigStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, - configName: configNew.ConfigName, + instanceID: instanceID, + configName: configNew.ConfigName, } if action == "PUT" { // PUT is proceeded by PUT or POST - err = applyConfig(rbName, rbVersion, profileName, configPrev, profileChannel, "PUT") + err = applyConfig(instanceID, configPrev, profileChannel, "PUT") if err != nil { return pkgerrors.Wrap(err, "Apply Config failed") } @@ -334,7 +339,7 @@ func (v *ConfigClient) Rollback(rbName, rbVersion, profileName string, rback Con } } else if action == "POST" { // POST is always preceeded by Config not existing - err = applyConfig(rbName, rbVersion, profileName, configNew, profileChannel, "DELETE") + err = applyConfig(instanceID, configNew, profileChannel, "DELETE") if err != nil { return pkgerrors.Wrap(err, "Delete Config failed") } @@ -344,7 +349,7 @@ func (v *ConfigClient) Rollback(rbName, rbVersion, profileName string, rback Con } } else if action == "DELETE" { // DELETE is proceeded by PUT or POST - err = applyConfig(rbName, rbVersion, profileName, configPrev, profileChannel, "PUT") + err = applyConfig(instanceID, configPrev, profileChannel, "PUT") if err != nil { return pkgerrors.Wrap(err, "Delete Config failed") } @@ -365,23 +370,25 @@ func (v *ConfigClient) Rollback(rbName, rbVersion, profileName string, rback Con } // Tagit tags the current version with the tag provided -func (v *ConfigClient) Tagit(rbName, rbVersion, profileName string, tag ConfigTagit) error { +func (v *ConfigClient) Tagit(instanceID string, tag ConfigTagit) error { - lock, _ := getProfileData(rbName + rbVersion + profileName) + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) + if err != nil { + return pkgerrors.Wrap(err, "Retrieving model info") + } + lock, _ := getProfileData(instanceID) // Acquire per profile Mutex lock.Lock() defer lock.Unlock() cvs := ConfigVersionStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, + instanceID: instanceID, } currentVersion, err := cvs.getCurrentVersion() if err != nil { return pkgerrors.Wrap(err, "Get Current Config Version ") } - tagKey := constructKey(rbName, rbVersion, profileName, v.tagTag, tag.TagName) + tagKey := constructKey(rbName, rbVersion, profileName, instanceID, v.tagTag, tag.TagName) err = db.Etcd.Put(tagKey, strconv.Itoa(int(currentVersion))) if err != nil { @@ -391,9 +398,13 @@ func (v *ConfigClient) Tagit(rbName, rbVersion, profileName string, tag ConfigTa } // GetTagVersion returns the version associated with the tag -func (v *ConfigClient) GetTagVersion(rbName, rbVersion, profileName, tagName string) (string, error) { +func (v *ConfigClient) GetTagVersion(instanceID, tagName string) (string, error) { - tagKey := constructKey(rbName, rbVersion, profileName, v.tagTag, tagName) + 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) value, err := db.Etcd.Get(tagKey) if err != nil { @@ -403,17 +414,15 @@ func (v *ConfigClient) GetTagVersion(rbName, rbVersion, profileName, tagName str } // ApplyAllConfig starts from first configuration version and applies all versions in sequence -func (v *ConfigClient) ApplyAllConfig(rbName, rbVersion, profileName string) error { +func (v *ConfigClient) ApplyAllConfig(instanceID string) error { - lock, profileChannel := getProfileData(rbName + rbVersion + profileName) + lock, profileChannel := getProfileData(instanceID) // Acquire per profile Mutex lock.Lock() defer lock.Unlock() cvs := ConfigVersionStore{ - rbName: rbName, - rbVersion: rbVersion, - profileName: profileName, + instanceID: instanceID, } currentVersion, err := cvs.getCurrentVersion() if err != nil { @@ -429,7 +438,7 @@ func (v *ConfigClient) ApplyAllConfig(rbName, rbVersion, profileName string) err if err != nil { return pkgerrors.Wrap(err, "Get Config Version") } - err = applyConfig(rbName, rbVersion, profileName, configNew, profileChannel, action) + err = applyConfig(instanceID, configNew, profileChannel, action) if err != nil { return pkgerrors.Wrap(err, "Apply Config failed") } diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go index 4cbe1da3..5771c83f 100644 --- a/src/k8splugin/internal/app/config_backend.go +++ b/src/k8splugin/internal/app/config_backend.go @@ -1,5 +1,6 @@ /* * Copyright 2018 Intel Corporation, Inc + * Copyright © 2021 Samsung Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,17 +45,13 @@ type configVersionDBContent struct { //ConfigStore to Store the Config type ConfigStore struct { - rbName string - rbVersion string - profileName string - configName string + instanceID string + configName string } //ConfigVersionStore to Store the Versions of the Config type ConfigVersionStore struct { - rbName string - rbVersion string - profileName string + instanceID string } type configResourceList struct { @@ -101,8 +98,12 @@ func constructKey(strs ...string) string { // Create an entry for the config in the database func (c ConfigStore) createConfig(p Config) error { - cfgKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagConfig, p.ConfigName) - _, err := db.Etcd.Get(cfgKey) + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID) + if err != nil { + return pkgerrors.Wrap(err, "Retrieving model info") + } + cfgKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagConfig, p.ConfigName) + _, err = db.Etcd.Get(cfgKey) if err == nil { return pkgerrors.Wrap(err, "Config DB Entry Already exists") } @@ -121,7 +122,11 @@ func (c ConfigStore) createConfig(p Config) error { // Returns the previous value of the Config func (c ConfigStore) updateConfig(p Config) (Config, error) { - cfgKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagConfig, p.ConfigName) + 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, p.ConfigName) value, err := db.Etcd.Get(cfgKey) configPrev := Config{} if err == nil { @@ -144,7 +149,11 @@ func (c ConfigStore) updateConfig(p Config) (Config, error) { // Read the config entry in the database func (c ConfigStore) getConfig() (Config, error) { - cfgKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagConfig, c.configName) + 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, c.configName) value, err := db.Etcd.Get(cfgKey) if err != nil { return Config{}, pkgerrors.Wrap(err, "Get Config DB Entry") @@ -164,7 +173,11 @@ func (c ConfigStore) getConfig() (Config, error) { // Delete the config entry in the database func (c ConfigStore) deleteConfig() (Config, error) { - cfgKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagConfig, c.configName) + 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, c.configName) value, err := db.Etcd.Get(cfgKey) if err != nil { return Config{}, pkgerrors.Wrap(err, "Config DB Entry Not found") @@ -190,7 +203,11 @@ func (c ConfigVersionStore) createConfigVersion(configNew, configPrev Config, ac if err != nil { return 0, pkgerrors.Wrap(err, "Get Next Version") } - versionKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagVersion, strconv.Itoa(int(version))) + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID) + if err != nil { + return 0, pkgerrors.Wrap(err, "Retrieving model info") + } + versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, strconv.Itoa(int(version))) var cs configVersionDBContent cs.Action = action @@ -216,7 +233,11 @@ func (c ConfigVersionStore) deleteConfigVersion() error { if err != nil { return pkgerrors.Wrap(err, "Get Next Version") } - versionKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagVersion, strconv.Itoa(int(counter))) + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(c.instanceID) + if err != nil { + return pkgerrors.Wrap(err, "Retrieving model info") + } + versionKey := constructKey(rbName, rbVersion, profileName, c.instanceID, tagVersion, strconv.Itoa(int(counter))) err = db.Etcd.Delete(versionKey) if err != nil { @@ -233,7 +254,11 @@ func (c ConfigVersionStore) deleteConfigVersion() error { // Also returns the action for the config version func (c ConfigVersionStore) getConfigVersion(version uint) (Config, Config, string, error) { - versionKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagVersion, strconv.Itoa(int(version))) + 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))) configBytes, err := db.Etcd.Get(versionKey) if err != nil { return Config{}, Config{}, "", pkgerrors.Wrap(err, "Get Config Version ") @@ -253,7 +278,11 @@ func (c ConfigVersionStore) getConfigVersion(version uint) (Config, Config, stri // Get the counter for the version func (c ConfigVersionStore) getCurrentVersion() (uint, error) { - cfgKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagCounter) + 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) value, err := db.Etcd.Get(cfgKey) if err != nil { @@ -275,8 +304,12 @@ func (c ConfigVersionStore) getCurrentVersion() (uint, error) { // Update the counter for the version func (c ConfigVersionStore) updateVersion(counter uint) error { - cfgKey := constructKey(c.rbName, c.rbVersion, c.profileName, tagCounter) - err := db.Etcd.Put(cfgKey, strconv.Itoa(int(counter))) + 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) + err = db.Etcd.Put(cfgKey, strconv.Itoa(int(counter))) if err != nil { return pkgerrors.Wrap(err, "Counter DB Entry") } @@ -318,8 +351,12 @@ func (c ConfigVersionStore) decrementVersion() error { } // Apply Config -func applyConfig(rbName, rbVersion, profileName string, p Config, pChannel chan configResourceList, action string) error { +func applyConfig(instanceID string, p Config, pChannel chan configResourceList, action string) error { + rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID) + if err != nil { + return pkgerrors.Wrap(err, "Retrieving model info") + } // Get Template and Resolve the template with values crl, err := resolve(rbName, rbVersion, profileName, p) if err != nil { @@ -362,12 +399,12 @@ func scheduleResources(c chan configResourceList) { } //assuming - the resource is not exist already data.createdResources, err = k8sClient.createResources(data.resourceTemplates, inst.Namespace) - errCreate := err + errCreate := err if err != nil { // assuming - the err represent the resource is already exist, so going for update data.createdResources, err = k8sClient.updateResources(data.resourceTemplates, inst.Namespace) if err != nil { - log.Printf("Error Creating resources: %s", errCreate.Error()) + log.Printf("Error Creating resources: %s", errCreate.Error()) log.Printf("Error Updating resources: %s", err.Error()) continue } @@ -405,7 +442,7 @@ var resolve = func(rbName, rbVersion, profileName string, p Config) (configResou profile, err := rb.NewProfileClient().Get(rbName, rbVersion, profileName) if err != nil { - return configResourceList{}, pkgerrors.Wrap(err, "Reading Profile Data") + return configResourceList{}, pkgerrors.Wrap(err, "Reading Profile Data") } t, err := rb.NewConfigTemplateClient().Get(rbName, rbVersion, p.TemplateName) diff --git a/src/k8splugin/internal/app/config_test.go b/src/k8splugin/internal/app/config_test.go index 38f0fa13..028895d7 100644 --- a/src/k8splugin/internal/app/config_test.go +++ b/src/k8splugin/internal/app/config_test.go @@ -1,5 +1,6 @@ /* * Copyright 2018 Intel Corporation, Inc + * Copyright © 2021 Samsung Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +18,7 @@ package app import ( + "fmt" "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" "reflect" "strings" @@ -24,12 +26,31 @@ import ( // pkgerrors "github.com/pkg/errors" ) +func provideMockModelData(instanceID, rbName, rbVersion, profileName string) *db.MockDB { + return &db.MockDB{ + Items: map[string]map[string][]byte{ + InstanceKey{ID: instanceID}.String(): { + "instance": []byte(fmt.Sprintf( + `{ + "id": "%s", + "request": { + "rb-name": "%s", + "rb-version": "%s", + "profile-name": "%s" + } + }`, instanceID, rbName, rbVersion, profileName)), + }, + }, + } +} + func TestCreateConfig(t *testing.T) { testCases := []struct { label string rbName string rbVersion string profileName string + instanceID string inp Config expectedError string mockdb *db.MockEtcdClient @@ -40,6 +61,7 @@ func TestCreateConfig(t *testing.T) { rbName: "testdef1", rbVersion: "v1", profileName: "testprofile1", + instanceID: "testinstance1", inp: Config{ ConfigName: "testconfig1", TemplateName: "testtemplate1", @@ -47,6 +69,7 @@ func TestCreateConfig(t *testing.T) { "values": "{\"namespace\": \"kafka\", \"topic\": {\"name\":\"orders\", \"cluster\":\"my-cluster\", \"partitions\": 10,\"replicas\": 2, }}"}, }, expected: ConfigResult{ + InstanceName: "testinstance1", DefinitionName: "testdef1", DefinitionVersion: "v1", ProfileName: "testprofile1", @@ -65,11 +88,13 @@ func TestCreateConfig(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.label, func(t *testing.T) { db.Etcd = testCase.mockdb + db.DBconn = provideMockModelData(testCase.instanceID, testCase.rbName, + testCase.rbVersion, testCase.profileName) resolve = func(rbName, rbVersion, profileName string, p Config) (configResourceList, error) { return configResourceList{}, nil } impl := NewConfigClient() - got, err := impl.Create(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.inp) + got, err := impl.Create(testCase.instanceID, testCase.inp) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) @@ -93,6 +118,7 @@ func TestRollbackConfig(t *testing.T) { rbName string rbVersion string profileName string + instanceID string inp Config inpUpdate1 Config inpUpdate2 Config @@ -109,6 +135,7 @@ func TestRollbackConfig(t *testing.T) { rbName: "testdef1", rbVersion: "v1", profileName: "testprofile1", + instanceID: "testinstance1", inp: Config{ ConfigName: "testconfig1", TemplateName: "testtemplate1", @@ -131,6 +158,7 @@ func TestRollbackConfig(t *testing.T) { DefinitionName: "testdef1", DefinitionVersion: "v1", ProfileName: "testprofile1", + InstanceName: "testinstance1", ConfigName: "testconfig1", TemplateName: "testtemplate1", ConfigVersion: 1, @@ -139,6 +167,7 @@ func TestRollbackConfig(t *testing.T) { DefinitionName: "testdef1", DefinitionVersion: "v1", ProfileName: "testprofile1", + InstanceName: "testinstance1", ConfigName: "testconfig1", TemplateName: "testtemplate1", ConfigVersion: 2, @@ -147,6 +176,7 @@ func TestRollbackConfig(t *testing.T) { DefinitionName: "testdef1", DefinitionVersion: "v1", ProfileName: "testprofile1", + InstanceName: "testinstance1", ConfigName: "testconfig1", TemplateName: "testtemplate1", ConfigVersion: 3, @@ -155,6 +185,7 @@ func TestRollbackConfig(t *testing.T) { DefinitionName: "testdef1", DefinitionVersion: "v1", ProfileName: "testprofile1", + InstanceName: "testinstance1", ConfigName: "testconfig1", TemplateName: "testtemplate1", ConfigVersion: 4, @@ -170,11 +201,13 @@ func TestRollbackConfig(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.label, func(t *testing.T) { db.Etcd = testCase.mockdb + db.DBconn = provideMockModelData(testCase.instanceID, testCase.rbName, + testCase.rbVersion, testCase.profileName) resolve = func(rbName, rbVersion, profileName string, p Config) (configResourceList, error) { return configResourceList{}, nil } impl := NewConfigClient() - got, err := impl.Create(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.inp) + got, err := impl.Create(testCase.instanceID, testCase.inp) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) @@ -188,7 +221,7 @@ func TestRollbackConfig(t *testing.T) { " expected %v", got, testCase.expected1) } } - got, err = impl.Update(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.inp.ConfigName, testCase.inpUpdate1) + got, err = impl.Update(testCase.instanceID, testCase.inp.ConfigName, testCase.inpUpdate1) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) @@ -202,7 +235,7 @@ func TestRollbackConfig(t *testing.T) { " expected %v", got, testCase.expected2) } } - got, err = impl.Update(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.inp.ConfigName, testCase.inpUpdate2) + got, err = impl.Update(testCase.instanceID, testCase.inp.ConfigName, testCase.inpUpdate2) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) @@ -216,7 +249,7 @@ func TestRollbackConfig(t *testing.T) { " expected %v", got, testCase.expected3) } } - got, err = impl.Delete(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.inp.ConfigName) + got, err = impl.Delete(testCase.instanceID, testCase.inp.ConfigName) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) @@ -231,7 +264,7 @@ func TestRollbackConfig(t *testing.T) { } } testCase.rollbackConfig.AnyOf.ConfigVersion = "2" - err = impl.Rollback(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.rollbackConfig) + err = impl.Rollback(testCase.instanceID, testCase.rollbackConfig) if err != nil { if testCase.expectedError == "" { t.Fatalf("Create returned an unexpected error %s", err) @@ -240,7 +273,7 @@ func TestRollbackConfig(t *testing.T) { t.Fatalf("Create returned an unexpected error %s", err) } } - rollbackConfig, err := impl.Get(testCase.rbName, testCase.rbVersion, testCase.profileName, testCase.inp.ConfigName) + rollbackConfig, err := impl.Get(testCase.instanceID, testCase.inp.ConfigName) 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 a6e213c1..69ade3a8 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -1,6 +1,6 @@ /* * Copyright 2018 Intel Corporation, Inc - * Copyright © 2020 Samsung Electronics + * Copyright © 2021 Samsung Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -111,6 +111,16 @@ func NewInstanceClient() *InstanceClient { } } +// Simplified function to retrieve model data from instance ID +func resolveModelFromInstance(instanceID string) (rbName, rbVersion, profileName, releaseName string, err error) { + v := NewInstanceClient() + resp, err := v.Get(instanceID) + if err != nil { + return "", "", "", "", pkgerrors.Wrap(err, "Getting instance") + } + return resp.Request.RBName, resp.Request.RBVersion, resp.Request.ProfileName, resp.ReleaseName, nil +} + // Create an instance of rb on the cluster in the database func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { -- cgit 1.2.3-korg