aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Rajewski <lukasz.rajewski@orange.com>2021-10-25 22:21:16 +0200
committerLukasz Rajewski <lukasz.rajewski@orange.com>2021-10-25 22:21:16 +0200
commit3f0da55c0183e9da2f4658308dee1915338266aa (patch)
treec2b9b4ad06786e51bf9262cb3d0dfacad7ee9853
parent6c28e5a7ca5a0688f5aefad010e0a3071ff6fe0b (diff)
Fix resolution of values for Config API0.9.3
Issue-ID: MULTICLOUD-1414 Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com> Change-Id: Ibca5846ffe083bfc4d505c4c3c13efac2c6e2426
-rw-r--r--src/k8splugin/internal/app/config_backend.go64
-rw-r--r--src/k8splugin/internal/app/config_test.go4
-rw-r--r--src/k8splugin/internal/app/instance.go27
-rw-r--r--src/k8splugin/internal/helm/helm.go6
-rw-r--r--src/k8splugin/internal/helm/helm_test.go2
-rw-r--r--src/k8splugin/internal/namegenerator/namegenerator.go20
-rw-r--r--src/k8splugin/internal/rb/profile.go31
7 files changed, 112 insertions, 42 deletions
diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go
index 1f22922a..c365363f 100644
--- a/src/k8splugin/internal/app/config_backend.go
+++ b/src/k8splugin/internal/app/config_backend.go
@@ -461,7 +461,7 @@ func applyConfig(instanceID string, p Config, pChannel chan configResourceList,
return []helm.KubernetesResource{}, pkgerrors.Wrap(err, "Retrieving model info")
}
// Get Template and Resolve the template with values
- crl, err := resolve(rbName, rbVersion, profileName, p, releaseName)
+ crl, err := resolve(rbName, rbVersion, profileName, instanceID, p, releaseName)
if err != nil {
return []helm.KubernetesResource{}, pkgerrors.Wrap(err, "Resolve Config")
}
@@ -571,11 +571,12 @@ func scheduleResources(c chan configResourceList) {
//Resolve returns the path where the helm chart merged with
//configuration overrides resides.
-var resolve = func(rbName, rbVersion, profileName string, p Config, releaseName string) (configResourceList, error) {
+var resolve = func(rbName, rbVersion, profileName, instanceId string, p Config, releaseName string) (configResourceList, error) {
var resTemplates []helm.KubernetesResourceTemplate
- profile, err := rb.NewProfileClient().Get(rbName, rbVersion, profileName)
+ profileClient := rb.NewProfileClient()
+ profile, err := profileClient.Get(rbName, rbVersion, profileName)
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Reading Profile Data")
}
@@ -593,8 +594,42 @@ var resolve = func(rbName, rbVersion, profileName string, p Config, releaseName
return configResourceList{}, pkgerrors.Wrap(err, "Downloading Template")
}
+ ic := NewInstanceClient()
+ instance, err := ic.Get(instanceId)
+ if err != nil {
+ return configResourceList{}, pkgerrors.Wrap(err, "Getting Instance")
+ }
+
+ var finalReleaseName string
+
+ if releaseName == "" {
+ finalReleaseName = profile.ReleaseName
+ } else {
+ finalReleaseName = releaseName
+ }
+
+ helmClient := helm.NewTemplateClient(profile.KubernetesVersion,
+ profile.Namespace,
+ finalReleaseName)
+
+ //copy values from the instance
+ valuesArr := []string{}
+ if instance.Request.OverrideValues != nil {
+ for k, v := range instance.Request.OverrideValues {
+ valuesArr = append(valuesArr, k+"="+v)
+ }
+ }
+ valuesArr = append(valuesArr, "k8s-rb-instance-id="+instanceId)
+ rawValues, err := helmClient.ProcessValues([]string{}, valuesArr)
+ if err != nil {
+ return configResourceList{}, pkgerrors.Wrap(err, "Processing values")
+ }
+
+ for k, v := range p.Values {
+ rawValues[k] = v
+ }
//Create a temp file in the system temp folder for values input
- b, err := json.Marshal(p.Values)
+ b, err := json.Marshal(rawValues)
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Error Marshalling config data")
}
@@ -613,26 +648,21 @@ var resolve = func(rbName, rbVersion, profileName string, p Config, releaseName
}
defer outputfile.Close()
- chartBasePath, err := rb.ExtractTarBall(bytes.NewBuffer(def))
+ //Download and process the profile first
+ //If everything seems okay, then download the config templates
+ prYamlClient, err := profileClient.GetYamlClient(rbName, rbVersion, profileName)
if err != nil {
- return configResourceList{}, pkgerrors.Wrap(err, "Extracting Template")
+ return configResourceList{}, pkgerrors.Wrap(err, "Processing Profile Manifest")
}
- var finalReleaseName string
-
- if releaseName == "" {
- finalReleaseName = profile.ReleaseName
- } else {
- finalReleaseName = releaseName
+ chartBasePath, err := rb.ExtractTarBall(bytes.NewBuffer(def))
+ if err != nil {
+ return configResourceList{}, pkgerrors.Wrap(err, "Extracting Template")
}
- helmClient := helm.NewTemplateClient(profile.KubernetesVersion,
- profile.Namespace,
- finalReleaseName)
-
chartPath := filepath.Join(chartBasePath, t.ChartName)
resTemplates, crdList, _, err := helmClient.GenerateKubernetesArtifacts(chartPath,
- []string{outputfile.Name()},
+ []string{prYamlClient.GetValues(), outputfile.Name()},
nil)
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Generate final k8s yaml")
diff --git a/src/k8splugin/internal/app/config_test.go b/src/k8splugin/internal/app/config_test.go
index 0cc3c3ce..1aef6656 100644
--- a/src/k8splugin/internal/app/config_test.go
+++ b/src/k8splugin/internal/app/config_test.go
@@ -91,7 +91,7 @@ func TestCreateConfig(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, releaseName string) (configResourceList, error) {
+ resolve = func(rbName, rbVersion, profileName, instanceId string, p Config, releaseName string) (configResourceList, error) {
return configResourceList{}, nil
}
impl := NewConfigClient()
@@ -204,7 +204,7 @@ func TestRollbackConfig(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, releaseName string) (configResourceList, error) {
+ resolve = func(rbName, rbVersion, profileName, instanceID string, p Config, releaseName string) (configResourceList, error) {
return configResourceList{}, nil
}
impl := NewConfigClient()
diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go
index e50a59e5..71042f08 100644
--- a/src/k8splugin/internal/app/instance.go
+++ b/src/k8splugin/internal/app/instance.go
@@ -224,18 +224,21 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
postDeleteTimeout = 600
}
+ id := namegenerator.Generate()
+
+ overrideValues = append(overrideValues, "k8s-rb-instance-id="+id)
+
//Execute the kubernetes create command
sortedTemplates, crdList, hookList, releaseName, err := rb.NewProfileClient().Resolve(i.RBName, i.RBVersion, i.ProfileName, overrideValues, i.ReleaseName)
if err != nil {
+ namegenerator.Release(id)
return InstanceResponse{}, pkgerrors.Wrap(err, "Error resolving helm charts")
}
- // TODO: Only generate if id is not provided
- id := namegenerator.Generate()
-
k8sClient := KubernetesClient{}
err = k8sClient.Init(i.CloudRegion, id)
if err != nil {
+ namegenerator.Release(id)
return InstanceResponse{}, pkgerrors.Wrap(err, "Getting CloudRegion Information")
}
@@ -273,19 +276,21 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
PostDeleteTimeout: postDeleteTimeout,
}
+ err = k8sClient.ensureNamespace(profile.Namespace)
+ if err != nil {
+ namegenerator.Release(id)
+ return InstanceResponse{}, pkgerrors.Wrap(err, "Creating Namespace")
+ }
+
key := InstanceKey{
ID: id,
}
err = db.DBconn.Create(v.storeName, key, v.tagInst, dbData)
if err != nil {
+ namegenerator.Release(id)
return InstanceResponse{}, pkgerrors.Wrap(err, "Creating Instance DB Entry")
}
- err = k8sClient.ensureNamespace(profile.Namespace)
- if err != nil {
- return InstanceResponse{}, pkgerrors.Wrap(err, "Creating Namespace")
- }
-
if len(crdList) > 0 {
log.Printf("Pre-Installing CRDs")
_, err = k8sClient.createResources(crdList, profile.Namespace)
@@ -303,6 +308,8 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
err2 := db.DBconn.Delete(v.storeName, key, v.tagInst)
if err2 != nil {
log.Printf("Error cleaning failed instance in DB, please check DB.")
+ } else {
+ namegenerator.Release(id)
}
return InstanceResponse{}, pkgerrors.Wrap(err, "Error running preinstall hooks")
}
@@ -314,6 +321,8 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
err2 := db.DBconn.Delete(v.storeName, key, v.tagInst)
if err2 != nil {
log.Printf("Delete Instance DB Entry for release %s has error.", releaseName)
+ } else {
+ namegenerator.Release(id)
}
return InstanceResponse{}, pkgerrors.Wrap(err, "Update Instance DB Entry")
}
@@ -330,6 +339,8 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
err2 := db.DBconn.Delete(v.storeName, key, v.tagInst)
if err2 != nil {
log.Printf("Delete Instance DB Entry for release %s has error.", releaseName)
+ } else {
+ namegenerator.Release(id)
}
return InstanceResponse{}, pkgerrors.Wrap(err, "Create Kubernetes Resources")
}
diff --git a/src/k8splugin/internal/helm/helm.go b/src/k8splugin/internal/helm/helm.go
index b27c8aee..846366e4 100644
--- a/src/k8splugin/internal/helm/helm.go
+++ b/src/k8splugin/internal/helm/helm.go
@@ -72,9 +72,9 @@ func NewTemplateClient(k8sversion, namespace, releasename string) *TemplateClien
}
}
-// Combines valueFiles and values into a single values stream.
+// ProcessValues Combines valueFiles and values into a single values stream.
// values takes precedence over valueFiles
-func (h *TemplateClient) processValues(valueFiles []string, values []string) (map[string]interface{}, error) {
+func (h *TemplateClient) ProcessValues(valueFiles []string, values []string) (map[string]interface{}, error) {
settings := cli.New()
providers := getter.All(settings)
options := helmOptions.Options{
@@ -121,7 +121,7 @@ func (h *TemplateClient) GenerateKubernetesArtifacts(inputPath string, valueFile
}
// get combined values and create config
- rawVals, err := h.processValues(valueFiles, values)
+ rawVals, err := h.ProcessValues(valueFiles, values)
if err != nil {
return retData, crdData, hookList, err
}
diff --git a/src/k8splugin/internal/helm/helm_test.go b/src/k8splugin/internal/helm/helm_test.go
index 951ff92b..8f0269ab 100644
--- a/src/k8splugin/internal/helm/helm_test.go
+++ b/src/k8splugin/internal/helm/helm_test.go
@@ -95,7 +95,7 @@ func TestProcessValues(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
tc := NewTemplateClient("1.12.3", "testnamespace", "testreleasename")
- out, err := tc.processValues(testCase.valueFiles, testCase.values)
+ out, err := tc.ProcessValues(testCase.valueFiles, testCase.values)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Got an error %s", err)
diff --git a/src/k8splugin/internal/namegenerator/namegenerator.go b/src/k8splugin/internal/namegenerator/namegenerator.go
index 52eef366..0a49633a 100644
--- a/src/k8splugin/internal/namegenerator/namegenerator.go
+++ b/src/k8splugin/internal/namegenerator/namegenerator.go
@@ -141,8 +141,28 @@ func (c *cache) generateName() string {
}
}
+func (c *cache) releaseName(name string) {
+ c.mux.Lock()
+ defer c.mux.Unlock()
+
+ c.init()
+
+ if c.isAlreadyUsed(name) {
+ c.cache[name] = false
+
+ // Update the cache and db
+ c.writeCacheToDB()
+ }
+}
+
// Generate returns an autogenerated name
func Generate() string {
return nameCache.generateName()
}
+
+// Release name from cache
+func Release(name string) {
+
+ nameCache.releaseName(name)
+}
diff --git a/src/k8splugin/internal/rb/profile.go b/src/k8splugin/internal/rb/profile.go
index 77398580..ac90a63b 100644
--- a/src/k8splugin/internal/rb/profile.go
+++ b/src/k8splugin/internal/rb/profile.go
@@ -279,6 +279,25 @@ func (v *ProfileClient) Download(rbName, rbVersion, prName string) ([]byte, erro
return nil, pkgerrors.New("Error downloading Profile content")
}
+//GetYamlClient GEt Yaml Files client for profile
+func (v *ProfileClient) GetYamlClient(rbName string, rbVersion string, profileName string) (ProfileYamlClient, error) {
+ prData, err := v.Download(rbName, rbVersion, profileName)
+ if err != nil {
+ return ProfileYamlClient{}, pkgerrors.Wrap(err, "Downloading Profile")
+ }
+
+ prPath, err := ExtractTarBall(bytes.NewBuffer(prData))
+ if err != nil {
+ return ProfileYamlClient{}, pkgerrors.Wrap(err, "Extracting Profile Content")
+ }
+
+ prYamlClient, err := ProcessProfileYaml(prPath, v.manifestName)
+ if err != nil {
+ return ProfileYamlClient{}, pkgerrors.Wrap(err, "Processing Profile Manifest")
+ }
+ return prYamlClient, nil
+}
+
//Resolve returns the path where the helm chart merged with
//configuration overrides resides and final ReleaseName picked for instantiation
func (v *ProfileClient) Resolve(rbName string, rbVersion string,
@@ -291,17 +310,7 @@ func (v *ProfileClient) Resolve(rbName string, rbVersion string,
//Download and process the profile first
//If everything seems okay, then download the definition
- prData, err := v.Download(rbName, rbVersion, profileName)
- if err != nil {
- return sortedTemplates, crdList, hookList, finalReleaseName, pkgerrors.Wrap(err, "Downloading Profile")
- }
-
- prPath, err := ExtractTarBall(bytes.NewBuffer(prData))
- if err != nil {
- return sortedTemplates, crdList, hookList, finalReleaseName, pkgerrors.Wrap(err, "Extracting Profile Content")
- }
-
- prYamlClient, err := ProcessProfileYaml(prPath, v.manifestName)
+ prYamlClient, err := v.GetYamlClient(rbName, rbVersion, profileName)
if err != nil {
return sortedTemplates, crdList, hookList, finalReleaseName, pkgerrors.Wrap(err, "Processing Profile Manifest")
}