aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/internal/app/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/k8splugin/internal/app/config.go')
-rw-r--r--src/k8splugin/internal/app/config.go312
1 files changed, 259 insertions, 53 deletions
diff --git a/src/k8splugin/internal/app/config.go b/src/k8splugin/internal/app/config.go
index 8952c16d..fce163fc 100644
--- a/src/k8splugin/internal/app/config.go
+++ b/src/k8splugin/internal/app/config.go
@@ -22,17 +22,17 @@ import (
"strconv"
"strings"
- "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
-
pkgerrors "github.com/pkg/errors"
)
// Config contains the parameters needed for configuration
type Config struct {
- ConfigName string `json:"config-name"`
- TemplateName string `json:"template-name"`
- Description string `json:"description"`
- Values map[string]interface{} `json:"values"`
+ ConfigName string `json:"config-name"`
+ TemplateName string `json:"template-name"`
+ Description string `json:"description"`
+ Values map[string]interface{} `json:"values"`
+ ConfigVersion uint `json:"config-version"`
+ ConfigTag string `json:"config-tag"`
}
//ConfigResult output for Create, Update and delete
@@ -54,6 +54,12 @@ type ConfigRollback struct {
} `json:"anyOf"`
}
+//ConfigRollback input
+type ConfigTag struct {
+ ConfigVersion uint `json:"config-version"`
+ ConfigTag string `json:"config-tag"`
+}
+
//ConfigTagit for Tagging configurations
type ConfigTagit struct {
TagName string `json:"tag-name"`
@@ -63,14 +69,18 @@ type ConfigTagit struct {
type ConfigManager interface {
Create(instanceID string, p Config) (ConfigResult, error)
Get(instanceID, configName string) (Config, error)
+ GetVersion(instanceID, configName, version string) (Config, error)
+ GetTag(instanceID, configName, tagName string) (Config, error)
List(instanceID string) ([]Config, error)
+ VersionList(instanceID, configName string) ([]Config, error)
Help() map[string]string
Update(instanceID, configName string, p Config) (ConfigResult, error)
Delete(instanceID, configName string) (ConfigResult, error)
- DeleteAll(instanceID, configName string) error
- Rollback(instanceID string, configName string, p ConfigRollback) error
+ DeleteAll(instanceID, configName string, deleteConfigOnly bool) error
+ Rollback(instanceID string, configName string, p ConfigRollback, acceptRevert bool) (ConfigResult, error)
Cleanup(instanceID string) error
- Tagit(instanceID string, configName string, p ConfigTagit) error
+ Tagit(instanceID string, configName string, p ConfigTagit) (ConfigTag, error)
+ TagList(instanceID, configName string) ([]ConfigTag, error)
}
// ConfigClient implements the ConfigManager
@@ -99,7 +109,7 @@ func (v *ConfigClient) Help() map[string]string {
func (v *ConfigClient) Create(instanceID string, p Config) (ConfigResult, error) {
log.Printf("[Config Create] Instance %s", instanceID)
// Check required fields
- if p.ConfigName == "" || p.TemplateName == "" || len(p.Values) == 0 {
+ if p.ConfigName == "" || p.TemplateName == "" {
return ConfigResult{}, pkgerrors.New("Incomplete Configuration Provided")
}
// Resolving rbName, Version, etc. not to break response
@@ -123,7 +133,7 @@ func (v *ConfigClient) Create(instanceID string, p Config) (ConfigResult, error)
// Acquire per profile Mutex
lock.Lock()
defer lock.Unlock()
- var appliedResources ([]helm.KubernetesResource)
+ var appliedResources ([]KubernetesConfigResource)
appliedResources, err = applyConfig(instanceID, p, profileChannel, "POST", nil)
if err != nil {
return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed")
@@ -160,10 +170,6 @@ func (v *ConfigClient) Create(instanceID string, p Config) (ConfigResult, error)
// Update an entry for the config in the database
func (v *ConfigClient) Update(instanceID, configName string, p Config) (ConfigResult, error) {
log.Printf("[Config Update] Instance %s Config %s", instanceID, configName)
- // 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 {
@@ -182,7 +188,7 @@ func (v *ConfigClient) Update(instanceID, configName string, p Config) (ConfigRe
// Acquire per profile Mutex
lock.Lock()
defer lock.Unlock()
- var appliedResources ([]helm.KubernetesResource)
+ var appliedResources ([]KubernetesConfigResource)
appliedResources, err = applyConfig(instanceID, p, profileChannel, "PUT", nil)
if err != nil {
return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed")
@@ -232,6 +238,59 @@ func (v *ConfigClient) Get(instanceID, configName string) (Config, error) {
if err != nil {
return Config{}, pkgerrors.Wrap(err, "Get Config DB Entry")
}
+
+ cvs := ConfigVersionStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ currentVersion, err := cvs.getCurrentVersion(configName)
+ if err != nil {
+ return Config{}, pkgerrors.Wrap(err, "Get Config Version Entry")
+ }
+ cfg.ConfigVersion = currentVersion
+ return cfg, nil
+}
+
+// Get version config entry in the database
+func (v *ConfigClient) GetTag(instanceID, configName, tagName string) (Config, error) {
+ cvs := ConfigVersionStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ version, err := cvs.getTagVersion(configName, tagName)
+ if err != nil {
+ return Config{}, pkgerrors.Wrap(err, "Get Config Tag Version Entry")
+ }
+ return v.GetVersion(instanceID, configName, version)
+}
+
+// Get version config entry in the database
+func (v *ConfigClient) GetVersion(instanceID, configName, version string) (Config, error) {
+
+ // Acquire per profile Mutex
+ lock, _ := getProfileData(instanceID)
+ lock.Lock()
+ defer lock.Unlock()
+ // Read Config DB
+ cs := ConfigStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ cfg, err := cs.getConfig()
+
+ cvs := ConfigVersionStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ versionInt, err := strconv.ParseUint(version, 0, 32)
+ if err != nil {
+ return Config{}, pkgerrors.Wrap(err, "Parsint version string")
+ }
+ _, _, _, _, err = cvs.getConfigVersion(configName, uint(versionInt))
+ if err != nil {
+ return Config{}, pkgerrors.Wrap(err, "Get Config Version Entry")
+ }
+ cfg.ConfigVersion = uint(versionInt)
return cfg, nil
}
@@ -247,14 +306,100 @@ func (v *ConfigClient) List(instanceID string) ([]Config, error) {
instanceID: instanceID,
}
cfg, err := cs.getConfigList()
+ result := make([]Config, 0)
+ for _, config := range cfg {
+ cvs := ConfigVersionStore{
+ instanceID: instanceID,
+ configName: config.ConfigName,
+ }
+ currentVersion, err := cvs.getCurrentVersion(config.ConfigName)
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Get Current Config Version ")
+ }
+ config.ConfigVersion = currentVersion
+ result = append(result, config)
+ }
if err != nil {
return []Config{}, pkgerrors.Wrap(err, "Get Config DB Entry")
}
- return cfg, nil
+ return result, nil
+}
+
+// Version List config entry in the database
+func (v *ConfigClient) VersionList(instanceID string, configName string) ([]Config, error) {
+
+ // Acquire per profile Mutex
+ lock, _ := getProfileData(instanceID)
+ lock.Lock()
+ defer lock.Unlock()
+
+ cvs := ConfigVersionStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ currentVersion, err := cvs.getCurrentVersion(configName)
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Get Current Config Version ")
+ }
+ //Get all configurations
+ var i uint
+ cfgList := make([]Config, 0)
+ for i = 1; i <= currentVersion; i++ {
+ config, _, _, _, err := cvs.getConfigVersion(configName, i)
+ config.ConfigVersion = i
+ if err != nil {
+ return []Config{}, pkgerrors.Wrap(err, "Get Config Version")
+ }
+ cfgList = append(cfgList, config)
+ }
+
+ return cfgList, nil
+}
+
+func (v *ConfigClient) TagList(instanceID, configName string) ([]ConfigTag, error) {
+
+ // Acquire per profile Mutex
+ lock, _ := getProfileData(instanceID)
+ lock.Lock()
+ defer lock.Unlock()
+ // Read Config DB
+ cs := ConfigStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ _, err := cs.getConfig()
+ if err != nil {
+ return []ConfigTag{}, pkgerrors.Wrap(err, "Get Config DB Entry")
+ }
+ cvs := ConfigVersionStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+
+ tagList, err := cvs.getTagList(configName)
+ if err != nil {
+ return []ConfigTag{}, pkgerrors.Wrap(err, "Get Tag list")
+ }
+ result := make([]ConfigTag, 0)
+ for _, tag := range tagList {
+ tagData := ConfigTag{}
+ version, err := cvs.getTagVersion(configName, tag)
+ if err != nil {
+ return []ConfigTag{}, pkgerrors.Wrap(err, "Get Tag version")
+ }
+ versionInt, err := strconv.ParseUint(version, 0, 32)
+ if err != nil {
+ return []ConfigTag{}, pkgerrors.Wrap(err, "Parsint version string")
+ }
+ tagData.ConfigTag = tag
+ tagData.ConfigVersion = uint(versionInt)
+ result = append(result, tagData)
+ }
+ return result, nil
}
// Delete the Config from database
-func (v *ConfigClient) DeleteAll(instanceID, configName string) error {
+func (v *ConfigClient) DeleteAll(instanceID, configName string, deleteConfigOnly bool) error {
log.Printf("[Config Delete All] Instance %s Config %s", instanceID, configName)
// Check if Config exists
cs := ConfigStore{
@@ -270,19 +415,13 @@ func (v *ConfigClient) DeleteAll(instanceID, configName string) error {
instanceID: instanceID,
configName: configName,
}
- currentVersion, err := cvs.getCurrentVersion(configName)
- if err != nil {
- return pkgerrors.Wrap(err, "Current version get failed")
- }
- _, _, action, _, err := cvs.getConfigVersion(configName, currentVersion)
- if err != nil {
- return pkgerrors.Wrap(err, "Config version get failed")
- }
- if action != "DELETE" {
- _, err = v.Delete(instanceID, configName)
+ if !deleteConfigOnly {
+ var rollbackConfig = ConfigRollback{}
+ rollbackConfig.AnyOf.ConfigVersion = "0"
+ _, err = v.Rollback(instanceID, configName, rollbackConfig, true)
if err != nil {
- return pkgerrors.Wrap(err, "Config DELETE version failed")
+ return pkgerrors.Wrap(err, "Rollback to base version")
}
}
// Delete Config from DB
@@ -339,7 +478,7 @@ func (v *ConfigClient) Delete(instanceID, configName string) (ConfigResult, erro
if err != nil {
return ConfigResult{}, pkgerrors.Wrap(err, "Update Config DB Entry")
}
- version, err := cvs.createConfigVersion(p, configPrev, "DELETE", []helm.KubernetesResource{})
+ version, err := cvs.createConfigVersion(p, configPrev, "DELETE", []KubernetesConfigResource{})
if err != nil {
return ConfigResult{}, pkgerrors.Wrap(err, "Create Delete Config Version DB Entry")
}
@@ -358,25 +497,28 @@ 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, configName string, rback ConfigRollback) error {
+func (v *ConfigClient) Rollback(instanceID string, configName string, rback ConfigRollback, acceptRevert bool) (ConfigResult, error) {
log.Printf("[Config Rollback] Instance %s Config %s", instanceID, configName)
var reqVersion string
var err error
-
+ rbName, rbVersion, profileName, _, err := resolveModelFromInstance(instanceID)
+ if err != nil {
+ return ConfigResult{}, pkgerrors.Wrap(err, "Retrieving model info")
+ }
if rback.AnyOf.ConfigTag != "" {
reqVersion, err = v.GetTagVersion(instanceID, configName, rback.AnyOf.ConfigTag)
if err != nil {
- return pkgerrors.Wrap(err, "Rollback Invalid tag")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Invalid tag")
}
} else if rback.AnyOf.ConfigVersion != "" {
reqVersion = rback.AnyOf.ConfigVersion
} else {
- return pkgerrors.Errorf("No valid Index for Rollback")
+ return ConfigResult{}, pkgerrors.Errorf("No valid Index for Rollback")
}
index, err := strconv.Atoi(reqVersion)
if err != nil {
- return pkgerrors.Wrap(err, "Rollback Invalid Index")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Invalid Index")
}
rollbackIndex := uint(index)
@@ -391,62 +533,114 @@ func (v *ConfigClient) Rollback(instanceID string, configName string, rback Conf
}
currentVersion, err := cvs.getCurrentVersion(configName)
if err != nil {
- return pkgerrors.Wrap(err, "Rollback Get Current Config Version ")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Get Current Config Version ")
+ }
+
+ if (rollbackIndex < 1 && !acceptRevert) || rollbackIndex >= currentVersion {
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Invalid Config Version")
}
- if rollbackIndex < 1 && rollbackIndex >= currentVersion {
- return pkgerrors.Wrap(err, "Rollback Invalid Config Version")
+ if rollbackIndex < 1 && acceptRevert {
+ rollbackIndex = 0
}
//Rollback all the intermettinent configurations
for i := currentVersion; i > rollbackIndex; i-- {
configNew, configPrev, _, resources, err := cvs.getConfigVersion(configName, i)
if err != nil {
- return pkgerrors.Wrap(err, "Rollback Get Config Version")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Get Config Version")
+ }
+ var prevAction string
+ if i == 1 {
+ prevAction = "POST"
+ configPrev.ConfigName = ""
+ configPrev.TemplateName = ""
+ configPrev.Values = make(map[string]interface{})
+ } else {
+ _, _, prevAction, _, err = cvs.getConfigVersion(configName, i-1)
}
- _, _, prevAction, _, err := cvs.getConfigVersion(configName, i-1)
+ log.Printf("ROLLBACK to version: %d", i-1)
if err != nil {
- return pkgerrors.Wrap(err, "Rollback Get Prev Config Version")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Get Prev Config Version")
}
cs := ConfigStore{
instanceID: instanceID,
configName: configNew.ConfigName,
}
if prevAction != "DELETE" {
+ var resourcesToDelete = make([]KubernetesConfigResource, 0)
+ for _, res := range resources {
+ if res.Status == "CREATED" {
+ resourcesToDelete = append(resourcesToDelete, res)
+ }
+ }
+ if len(resourcesToDelete) > 0 {
+ _, err := applyConfig(instanceID, configPrev, profileChannel, "DELETE", resources)
+ if err != nil {
+ return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed")
+ }
+ }
appliedResources, err := applyConfig(instanceID, configPrev, profileChannel, prevAction, nil)
if err != nil {
- return pkgerrors.Wrap(err, "Apply Config failed")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Apply Config failed")
}
log.Printf("%s result: %s", prevAction, appliedResources)
_, err = cs.updateConfig(configPrev)
if err != nil {
- return pkgerrors.Wrap(err, "Update Config DB Entry")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Update Config DB Entry")
}
} else {
// POST is always preceeded by Config not existing
- _, err := applyConfig(instanceID, configNew, profileChannel, prevAction, resources)
+ _, err := applyConfig(instanceID, configPrev, profileChannel, prevAction, resources)
if err != nil {
- return pkgerrors.Wrap(err, "Delete Config failed")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Delete Config failed")
}
log.Printf("DELETE resources: %s", resources)
_, err = cs.updateConfig(configPrev)
if err != nil {
- return pkgerrors.Wrap(err, "Update Config DB Entry")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Update Config DB Entry")
}
}
}
+ if rollbackIndex == 0 {
+ //this is used only for delete config and remianing configuration 1 will be removed there
+ rollbackIndex = 1
+ }
for i := currentVersion; i > rollbackIndex; i-- {
// Delete rolled back items
err = cvs.deleteConfigVersion(configName)
if err != nil {
- return pkgerrors.Wrap(err, "Delete Config Version ")
+ return ConfigResult{}, pkgerrors.Wrap(err, "Delete Config Version ")
}
}
- return nil
+ currentVersion, err = cvs.getCurrentVersion(configName)
+ if err != nil {
+ return ConfigResult{}, pkgerrors.Wrap(err, "Rollback Get Current Config Version ")
+ }
+ // Check if Config exists
+ cs := ConfigStore{
+ instanceID: instanceID,
+ configName: configName,
+ }
+ currentConfig, err := cs.getConfig()
+ if err != nil {
+ return ConfigResult{}, pkgerrors.Wrap(err, "Update Error - Config doesn't exist")
+ }
+ // Create Result structure
+ cfgRes := ConfigResult{
+ InstanceName: instanceID,
+ DefinitionName: rbName,
+ DefinitionVersion: rbVersion,
+ ProfileName: profileName,
+ ConfigName: configName,
+ TemplateName: currentConfig.TemplateName,
+ ConfigVersion: currentVersion,
+ }
+ return cfgRes, nil
}
// Tagit tags the current version with the tag provided
-func (v *ConfigClient) Tagit(instanceID string, configName string, tag ConfigTagit) error {
+func (v *ConfigClient) Tagit(instanceID string, configName string, tag ConfigTagit) (ConfigTag, error) {
log.Printf("[Config Tag It] Instance %s Config %s", instanceID, configName)
lock, _ := getProfileData(instanceID)
// Acquire per profile Mutex
@@ -459,9 +653,17 @@ func (v *ConfigClient) Tagit(instanceID string, configName string, tag ConfigTag
}
err := cvs.tagCurrentVersion(configName, tag.TagName)
if err != nil {
- return pkgerrors.Wrap(err, "Tag of current version failed")
+ return ConfigTag{}, pkgerrors.Wrap(err, "Tag of current version failed")
}
- return nil
+ currentVersion, err := cvs.getCurrentVersion(configName)
+ if err != nil {
+ return ConfigTag{}, pkgerrors.Wrap(err, "Rollback Get Current Config Version ")
+ }
+
+ var tagResult = ConfigTag{}
+ tagResult.ConfigVersion = currentVersion
+ tagResult.ConfigTag = tag.TagName
+ return tagResult, nil
}
// GetTagVersion returns the version associated with the tag
@@ -489,7 +691,11 @@ func (v *ConfigClient) Cleanup(instanceID string) error {
}
for _, config := range configs {
- err = v.DeleteAll(instanceID, config.ConfigName)
+ _, err = v.Delete(instanceID, config.ConfigName)
+ if err != nil {
+ log.Printf("Config %s delete failed: %s", config.ConfigName, err.Error())
+ }
+ err = v.DeleteAll(instanceID, config.ConfigName, true)
if err != nil {
log.Printf("Config %s delete failed: %s", config.ConfigName, err.Error())
}
@@ -529,7 +735,7 @@ func (v *ConfigClient) ApplyAllConfig(instanceID string, configName string) erro
if action != "DELETE" {
resources = nil
}
- var appliedResources ([]helm.KubernetesResource)
+ var appliedResources ([]KubernetesConfigResource)
appliedResources, err = applyConfig(instanceID, configNew, profileChannel, action, resources)
if err != nil {
return pkgerrors.Wrap(err, "Apply Config failed")