From 4f8de90e2f8d43654e0418140bcead190b7293e1 Mon Sep 17 00:00:00 2001
From: Oleksii Kliukin <oleksii.kliukin@zalando.de>
Date: Wed, 22 Nov 2017 18:40:27 +0100
Subject: [PATCH] Expand variables from the PodEnvironmentConfigMap

Inject PodEnvironmentConfigMap variables inline into the
statefulset definition in order to be able to figure out
changes to the statefulset when only PodEnvironmentConfigMap
has changed.
---
 pkg/cluster/k8sres.go | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go
index 0ef31e26..4cf90333 100644
--- a/pkg/cluster/k8sres.go
+++ b/pkg/cluster/k8sres.go
@@ -262,7 +262,7 @@ func (c *Cluster) tolerations(tolerationsSpec *[]v1.Toleration) []v1.Toleration
 	}
 
 	podToleration := c.Config.OpConfig.PodToleration
-	if (len(podToleration["key"]) > 0 || len(podToleration["operator"]) > 0 || len(podToleration["value"]) > 0 || len(podToleration["effect"]) > 0) {
+	if len(podToleration["key"]) > 0 || len(podToleration["operator"]) > 0 || len(podToleration["value"]) > 0 || len(podToleration["effect"]) > 0 {
 		return []v1.Toleration{
 			{
 				Key:      podToleration["key"],
@@ -280,7 +280,8 @@ func (c *Cluster) generatePodTemplate(resourceRequirements *v1.ResourceRequireme
 	tolerationsSpec *[]v1.Toleration,
 	pgParameters *spec.PostgresqlParam,
 	patroniParameters *spec.Patroni,
-	cloneDescription *spec.CloneDescription) *v1.PodTemplateSpec {
+	cloneDescription *spec.CloneDescription,
+	extraEnv map[string]string) *v1.PodTemplateSpec {
 	spiloConfiguration := c.generateSpiloJSONConfiguration(pgParameters, patroniParameters)
 
 	envVars := []v1.EnvVar{
@@ -362,10 +363,23 @@ func (c *Cluster) generatePodTemplate(resourceRequirements *v1.ResourceRequireme
 		envVars = append(envVars, c.generateCloneEnvironment(cloneDescription)...)
 	}
 
-	envFromSource := []v1.EnvFromSource{}
-	if c.OpConfig.PodEnvironmentConfigMap != "" {
-		configMapRef := v1.ConfigMapEnvSource{LocalObjectReference: v1.LocalObjectReference{Name: c.OpConfig.PodEnvironmentConfigMap}}
-		envFromSource = append(envFromSource, v1.EnvFromSource{ConfigMapRef: &configMapRef})
+	var names []string
+	// handle environment variables from the PodEnvironmentConfigMap. We don't use envSource here as it is impossible
+	// to track any changes to the object envSource points to. In order to emulate the envSource behavior, however, we
+	// need to make sure that PodConfigMap variables doesn't override those we set explicitely from the configuration
+	// parameters
+	envVarsMap := make(map[string]string)
+	for _, envVar := range envVars {
+		envVarsMap[envVar.Name] = envVar.Value
+	}
+	for name := range extraEnv {
+		if _, ok := envVarsMap[name]; !ok {
+			names = append(names, name)
+		}
+	}
+	sort.Strings(names)
+	for _, name := range names {
+		envVars = append(envVars, v1.EnvVar{Name: name, Value: extraEnv[name]})
 	}
 
 	privilegedMode := true
@@ -395,7 +409,6 @@ func (c *Cluster) generatePodTemplate(resourceRequirements *v1.ResourceRequireme
 			},
 		},
 		Env: envVars,
-		EnvFrom: envFromSource,
 		SecurityContext: &v1.SecurityContext{
 			Privileged: &privilegedMode,
 		},
@@ -429,8 +442,16 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
 	if err != nil {
 		return nil, fmt.Errorf("could not generate resource requirements: %v", err)
 	}
+	var extraEnv map[string]string
+	if c.OpConfig.PodEnvironmentConfigMap != "" {
+		if cm, err := c.KubeClient.ConfigMaps(c.Namespace).Get(c.OpConfig.PodEnvironmentConfigMap, metav1.GetOptions{}); err != nil {
+			return nil, fmt.Errorf("could not read PodEnvironmentConfigMap: %v", err)
+		} else {
+			extraEnv = cm.Data
+		}
 
-	podTemplate := c.generatePodTemplate(resourceRequirements, &spec.Tolerations, &spec.PostgresqlParam, &spec.Patroni, &spec.Clone)
+	}
+	podTemplate := c.generatePodTemplate(resourceRequirements, &spec.Tolerations, &spec.PostgresqlParam, &spec.Patroni, &spec.Clone, extraEnv)
 	volumeClaimTemplate, err := generatePersistentVolumeClaimTemplate(spec.Volume.Size, spec.Volume.StorageClass)
 	if err != nil {
 		return nil, fmt.Errorf("could not generate volume claim template: %v", err)
-- 
GitLab