Changed behavio on environment
- variables are all in values.yaml as "template string". This means that we can now set values to reference others (useful with mapenv label) - we can also set any variable as a secret
This commit is contained in:
@@ -59,14 +59,27 @@ func CreateReplicaObject(name string, s types.ServiceConfig, linked map[string]t
|
|||||||
|
|
||||||
// This function will try to yied deployment and services based on a service from the compose file structure.
|
// This function will try to yied deployment and services based on a service from the compose file structure.
|
||||||
func parseService(name string, s types.ServiceConfig, linked map[string]types.ServiceConfig, ret chan interface{}) {
|
func parseService(name string, s types.ServiceConfig, linked map[string]types.ServiceConfig, ret chan interface{}) {
|
||||||
|
// TODO: this function is a mess, need a complete refactorisation
|
||||||
|
|
||||||
logger.Magenta(ICON_PACKAGE+" Generating deployment for ", name)
|
logger.Magenta(ICON_PACKAGE+" Generating deployment for ", name)
|
||||||
|
deployment := helm.NewDeployment(name)
|
||||||
|
|
||||||
// adapt env
|
// adapt env
|
||||||
applyEnvMapLabel(&s)
|
applyEnvMapLabel(&s)
|
||||||
setEnvToValues(name, &s)
|
|
||||||
|
|
||||||
deployment := helm.NewDeployment(name)
|
// create a container for the deployment.
|
||||||
container := helm.NewContainer(name, s.Image, s.Environment, s.Labels)
|
container := helm.NewContainer(name, s.Image, s.Environment, s.Labels)
|
||||||
|
|
||||||
|
// If some variables are secrets, set them now !
|
||||||
|
if secretFile := setSecretVar(name, &s, container); secretFile != nil {
|
||||||
|
ret <- secretFile
|
||||||
|
container.EnvFrom = append(container.EnvFrom, map[string]map[string]string{
|
||||||
|
"secretRef": {
|
||||||
|
"name": secretFile.Metadata().Name,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setEnvToValues(name, &s, container)
|
||||||
prepareContainer(container, s, name)
|
prepareContainer(container, s, name)
|
||||||
prepareEnvFromFiles(name, s, container, ret)
|
prepareEnvFromFiles(name, s, container, ret)
|
||||||
|
|
||||||
@@ -90,8 +103,18 @@ func parseService(name string, s types.ServiceConfig, linked map[string]types.Se
|
|||||||
// Now, the linked services
|
// Now, the linked services
|
||||||
for lname, link := range linked {
|
for lname, link := range linked {
|
||||||
applyEnvMapLabel(&link)
|
applyEnvMapLabel(&link)
|
||||||
setEnvToValues(lname, &link)
|
|
||||||
container := helm.NewContainer(lname, link.Image, link.Environment, link.Labels)
|
container := helm.NewContainer(lname, link.Image, link.Environment, link.Labels)
|
||||||
|
|
||||||
|
// If some variables are secrets, set them now !
|
||||||
|
if secretFile := setSecretVar(lname, &link, container); secretFile != nil {
|
||||||
|
ret <- secretFile
|
||||||
|
container.EnvFrom = append(container.EnvFrom, map[string]map[string]string{
|
||||||
|
"secretRef": {
|
||||||
|
"name": secretFile.Metadata().Name,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setEnvToValues(lname, &link, container)
|
||||||
prepareContainer(container, link, lname)
|
prepareContainer(container, link, lname)
|
||||||
prepareEnvFromFiles(lname, link, container, ret)
|
prepareEnvFromFiles(lname, link, container, ret)
|
||||||
deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, container)
|
deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, container)
|
||||||
@@ -321,23 +344,23 @@ func prepareVolumes(deployment, name string, s types.ServiceConfig, container *h
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
isCM := false
|
isConfigMap := false
|
||||||
for _, cmVol := range configMapsVolumes {
|
for _, cmVol := range configMapsVolumes {
|
||||||
cmVol = strings.TrimSpace(cmVol)
|
cmVol = strings.TrimSpace(cmVol)
|
||||||
if volname == cmVol {
|
if volname == cmVol {
|
||||||
isCM = true
|
isConfigMap = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isCM && (strings.HasPrefix(volname, ".") || strings.HasPrefix(volname, "/")) {
|
if !isConfigMap && (strings.HasPrefix(volname, ".") || strings.HasPrefix(volname, "/")) {
|
||||||
// local volume cannt be mounted
|
// local volume cannt be mounted
|
||||||
logger.ActivateColors = true
|
logger.ActivateColors = true
|
||||||
logger.Redf("You cannot, at this time, have local volume in %s deployment\n", name)
|
logger.Redf("You cannot, at this time, have local volume in %s deployment\n", name)
|
||||||
logger.ActivateColors = false
|
logger.ActivateColors = false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if isCM {
|
if isConfigMap {
|
||||||
// check if the volname path points on a file, if so, we need to add subvolume to the interface
|
// check if the volname path points on a file, if so, we need to add subvolume to the interface
|
||||||
stat, err := os.Stat(volname)
|
stat, err := os.Stat(volname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -690,16 +713,52 @@ func applyEnvMapLabel(s *types.ServiceConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setEnvToValues will set the environment variables to the values.yaml map.
|
// setEnvToValues will set the environment variables to the values.yaml map.
|
||||||
func setEnvToValues(name string, s *types.ServiceConfig) {
|
func setEnvToValues(name string, s *types.ServiceConfig, c *helm.Container) {
|
||||||
// crete the "environment" key
|
// crete the "environment" key
|
||||||
|
|
||||||
env := make(map[string]interface{})
|
env := make(map[string]interface{})
|
||||||
for k, v := range s.Environment {
|
for k, v := range s.Environment {
|
||||||
env[k] = v
|
env[k] = v
|
||||||
}
|
}
|
||||||
|
if len(env) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
AddValues(name, map[string]interface{}{"environment": env})
|
AddValues(name, map[string]interface{}{"environment": env})
|
||||||
for k := range s.Environment {
|
for k := range env {
|
||||||
v := "{{ .Values." + name + ".environment." + k + " }}"
|
v := "{{ tpl .Values." + name + ".environment." + k + " . }}"
|
||||||
s.Environment[k] = &v
|
s.Environment[k] = &v
|
||||||
|
for _, c := range c.Env {
|
||||||
|
if c.Name == k {
|
||||||
|
c.Value = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setSecretVar(name string, s *types.ServiceConfig, c *helm.Container) *helm.Secret {
|
||||||
|
// get the list of secret vars
|
||||||
|
secretvars, ok := s.Labels[helm.LABEL_SECRETVARS]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
store := helm.NewSecret(name + "-secrets")
|
||||||
|
for _, secretvar := range strings.Split(secretvars, ",") {
|
||||||
|
// get the value from env
|
||||||
|
_, ok := s.Environment[secretvar]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// add the secret
|
||||||
|
store.AddEnv(secretvar, ".Values."+name+".environment."+secretvar)
|
||||||
|
envs := c.Env
|
||||||
|
for i, env := range envs {
|
||||||
|
if env.Name == secretvar {
|
||||||
|
envs = append(envs[:i], envs[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Env = envs
|
||||||
|
}
|
||||||
|
return store
|
||||||
|
}
|
||||||
|
@@ -50,7 +50,8 @@ services:
|
|||||||
ANOTHER_ENV_VAR: another_value
|
ANOTHER_ENV_VAR: another_value
|
||||||
DB_HOST: database
|
DB_HOST: database
|
||||||
labels:
|
labels:
|
||||||
katenary.io/env-to-service: DB_HOST
|
katenary.io/mapenv: |
|
||||||
|
DB_HOST: {{ .Release.Name }}-database
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: mysql:5.7
|
image: mysql:5.7
|
||||||
@@ -221,20 +222,20 @@ func TestEnvs(t *testing.T) {
|
|||||||
lines, _ := ioutil.ReadAll(fp)
|
lines, _ := ioutil.ReadAll(fp)
|
||||||
next := false
|
next := false
|
||||||
for _, line := range strings.Split(string(lines), "\n") {
|
for _, line := range strings.Split(string(lines), "\n") {
|
||||||
if strings.Contains(line, "DB_HOST") {
|
if !next && strings.Contains(line, "name: DB_HOST") {
|
||||||
next = true
|
next = true
|
||||||
continue
|
continue
|
||||||
}
|
} else if next && strings.Contains(line, "value:") {
|
||||||
if next {
|
|
||||||
matched = true
|
matched = true
|
||||||
if !strings.Contains(line, helm.ReleaseNameTpl+"-database") {
|
if !strings.Contains(line, "{{ tpl .Values.php.environment.DB_HOST . }}") {
|
||||||
t.Error("DB_HOST variable should be set to " + helm.ReleaseNameTpl + "-database")
|
t.Error("DB_HOST variable should be set to {{ tpl .Values.php.environment.DB_HOST . }}", line, string(lines))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !matched {
|
if !matched {
|
||||||
t.Error("DB_HOST variable not found in ", path)
|
t.Error("DB_HOST variable not found in ", path)
|
||||||
|
t.Log(string(lines))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,8 +383,9 @@ func TestEqualSignOnEnv(t *testing.T) {
|
|||||||
match++
|
match++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if match != 2 {
|
if match != 4 { // because the value points on .Values...
|
||||||
t.Error("eqenv service should have 2 environment variables")
|
t.Error("eqenv service should have 2 environment variables")
|
||||||
|
t.Log(string(lines))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
// InlineConfig is made to represent a configMap or a secret
|
// InlineConfig is made to represent a configMap or a secret
|
||||||
type InlineConfig interface {
|
type InlineConfig interface {
|
||||||
AddEnvFile(filename string) error
|
AddEnvFile(filename string) error
|
||||||
|
AddEnv(key, val string) error
|
||||||
Metadata() *Metadata
|
Metadata() *Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,9 +57,12 @@ func (c *ConfigMap) AddEnvFile(file string) error {
|
|||||||
}
|
}
|
||||||
c.Data[parts[0]] = parts[1]
|
c.Data[parts[0]] = parts[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ConfigMap) AddEnv(key, val string) error {
|
||||||
|
c.Data[key] = val
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secret is made to represent a secret with data.
|
// Secret is made to represent a secret with data.
|
||||||
@@ -108,3 +112,9 @@ func (s *Secret) AddEnvFile(file string) error {
|
|||||||
func (s *Secret) Metadata() *Metadata {
|
func (s *Secret) Metadata() *Metadata {
|
||||||
return s.K8sBase.Metadata
|
return s.K8sBase.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddEnv adds an environment variable to the secret.
|
||||||
|
func (s *Secret) AddEnv(key, val string) error {
|
||||||
|
s.Data[key] = fmt.Sprintf(`{{ %s | b64enc }}`, val)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -16,6 +16,7 @@ const (
|
|||||||
LABEL_SAMEPOD = K + "/same-pod"
|
LABEL_SAMEPOD = K + "/same-pod"
|
||||||
LABEL_EMPTYDIRS = K + "/empty-dirs"
|
LABEL_EMPTYDIRS = K + "/empty-dirs"
|
||||||
LABEL_IGNORE = K + "/ignore"
|
LABEL_IGNORE = K + "/ignore"
|
||||||
|
LABEL_SECRETVARS = K + "/secret-vars"
|
||||||
|
|
||||||
//deprecated: use LABEL_MAP_ENV instead
|
//deprecated: use LABEL_MAP_ENV instead
|
||||||
LABEL_ENV_SERVICE = K + "/env-to-service"
|
LABEL_ENV_SERVICE = K + "/env-to-service"
|
||||||
@@ -26,6 +27,7 @@ func GetLabelsDocumentation() string {
|
|||||||
t, _ := template.New("labels").Parse(`
|
t, _ := template.New("labels").Parse(`
|
||||||
# Labels
|
# Labels
|
||||||
{{.LABEL_IGNORE | printf "%-33s"}}: ignore the container, it will not yied any object in the helm chart
|
{{.LABEL_IGNORE | printf "%-33s"}}: ignore the container, it will not yied any object in the helm chart
|
||||||
|
{{.LABEL_SECRETVARS | printf "%-33s"}}: secret variables to push on a secret file
|
||||||
{{.LABEL_ENV_SECRET | printf "%-33s"}}: set the given file names as a secret instead of configmap
|
{{.LABEL_ENV_SECRET | printf "%-33s"}}: set the given file names as a secret instead of configmap
|
||||||
{{.LABEL_MAP_ENV | printf "%-33s"}}: map environment variable to a template string (yaml style)
|
{{.LABEL_MAP_ENV | printf "%-33s"}}: map environment variable to a template string (yaml style)
|
||||||
{{.LABEL_PORT | printf "%-33s"}}: set the ports to expose as a service (coma separated)
|
{{.LABEL_PORT | printf "%-33s"}}: set the ports to expose as a service (coma separated)
|
||||||
@@ -52,6 +54,7 @@ func GetLabelsDocumentation() string {
|
|||||||
"LABEL_EMPTYDIRS": LABEL_EMPTYDIRS,
|
"LABEL_EMPTYDIRS": LABEL_EMPTYDIRS,
|
||||||
"LABEL_IGNORE": LABEL_IGNORE,
|
"LABEL_IGNORE": LABEL_IGNORE,
|
||||||
"LABEL_MAP_ENV": LABEL_MAP_ENV,
|
"LABEL_MAP_ENV": LABEL_MAP_ENV,
|
||||||
|
"LABEL_SECRETVARS": LABEL_SECRETVARS,
|
||||||
})
|
})
|
||||||
return buff.String()
|
return buff.String()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user