From b1b96d83184c624901b0012c345e4854eba25b0c Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Fri, 6 May 2022 20:18:10 +0200 Subject: [PATCH] A big commit to fix more things, see details - ingress can now have annotations - configmaps are better named and there is a label to know from where the content is taken - fixed bad "nil" pointer checks - we force to not resolve paths from compose file, this should be a problem when we call the compose file from outside. So, TODO: check this! - the "project" label is now the Chart Name, not a static string - minor fixes --- compose/parser.go | 2 +- generator/main.go | 34 ++++++++++++++++++++-------------- generator/writer.go | 15 +++++++++++++-- generator/writers/configmap.go | 2 +- generator/writers/ingress.go | 9 +++++++++ helm/configAndSecretMap.go | 10 ++++++++-- helm/container.go | 1 - helm/k8sbase.go | 17 ++++++++++++++++- 8 files changed, 68 insertions(+), 22 deletions(-) diff --git a/compose/parser.go b/compose/parser.go index ca95fd7..81e54bf 100644 --- a/compose/parser.go +++ b/compose/parser.go @@ -69,7 +69,7 @@ func (p *Parser) Parse(appname string) { cli.WithDefaultConfigPath, cli.WithNormalization(true), cli.WithInterpolation(true), - cli.WithResolvedPaths(true), + //cli.WithResolvedPaths(true), ) if err != nil { log.Fatal(err) diff --git a/generator/main.go b/generator/main.go index cec719f..7fc8fea 100644 --- a/generator/main.go +++ b/generator/main.go @@ -195,11 +195,15 @@ func generateServicesAndIngresses(name string, s *types.ServiceConfig) []HelmFil func createIngress(name string, port int, s *types.ServiceConfig) *helm.Ingress { ingress := helm.NewIngress(name) + annotations := map[string]string{} ingressVal := map[string]interface{}{ - "class": "nginx", - "host": name + "." + helm.Appname + ".tld", - "enabled": false, + "class": "nginx", + "host": name + "." + helm.Appname + ".tld", + "enabled": false, + "annotations": annotations, } + + // add Annotations in values AddValues(name, map[string]EnvVal{"ingress": ingressVal}) ingress.Spec.Rules = []helm.IngressRule{ @@ -235,7 +239,7 @@ func buildSelector(name string, s *types.ServiceConfig) map[string]string { } // buildCMFromPath generates a ConfigMap from a path. -func buildCMFromPath(path string) *helm.ConfigMap { +func buildCMFromPath(name, path string) *helm.ConfigMap { stat, err := os.Stat(path) if err != nil { return nil @@ -262,7 +266,7 @@ func buildCMFromPath(path string) *helm.ConfigMap { } } - cm := helm.NewConfigMap("") + cm := helm.NewConfigMap(name, path) cm.Data = files return cm } @@ -354,11 +358,11 @@ func prepareVolumes(deployment, name string, s *types.ServiceConfig, container * } // the volume is a path and it's explicitally asked to be a configmap in labels - cm := buildCMFromPath(volname) + cm := buildCMFromPath(name, volname) volname = strings.Replace(volname, "./", "", 1) volname = strings.ReplaceAll(volname, "/", "-") volname = strings.ReplaceAll(volname, ".", "-") - cm.K8sBase.Metadata.Name = helm.ReleaseNameTpl + "-" + volname + "-" + name + cm.K8sBase.Metadata.Name = helm.ReleaseNameTpl + "-" + name + "-" + volname // build a configmap from the volume path volumes = append(volumes, map[string]interface{}{ @@ -570,7 +574,6 @@ func prepareEnvFromFiles(name string, s *types.ServiceConfig, container *helm.Co f = strings.ReplaceAll(f, ".env", "") f = strings.ReplaceAll(f, ".", "") f = strings.ReplaceAll(f, "/", "") - cf := f + "-" + name isSecret := false for _, s := range secretsFiles { s = strings.TrimSpace(s) @@ -580,11 +583,11 @@ func prepareEnvFromFiles(name string, s *types.ServiceConfig, container *helm.Co } var store helm.InlineConfig if !isSecret { - logger.Bluef(ICON_CONF+" Generating configMap %s\n", cf) - store = helm.NewConfigMap(cf) + logger.Bluef(ICON_CONF+" Generating configMap from %s\n", envfile) + store = helm.NewConfigMap(name, envfile) } else { - logger.Bluef(ICON_SECRET+" Generating secret %s\n", cf) - store = helm.NewSecret(cf) + logger.Bluef(ICON_SECRET+" Generating secret from %s\n", envfile) + store = helm.NewSecret(name, envfile) } envfile = filepath.Join(compose.GetCurrentDir(), envfile) @@ -620,7 +623,7 @@ func prepareEnvFromFiles(name string, s *types.ServiceConfig, container *helm.Co } if store != nil { - fileGeneratorChan <- store + fileGeneratorChan <- store.(HelmFile) } } } @@ -695,6 +698,9 @@ func applyEnvMapLabel(s *types.ServiceConfig, c *helm.Container) { vstring := fmt.Sprintf("%v", v) s.Environment[k] = &vstring touched := false + if c.Env != nil { + c.Env = make([]*helm.Value, 0) + } for _, env := range c.Env { if env.Name == k { env.Value = v @@ -745,7 +751,7 @@ func setSecretVar(name string, s *types.ServiceConfig, c *helm.Container) *helm. return nil } - store := helm.NewSecret(name + "-secrets") + store := helm.NewSecret(name, "") for _, secretvar := range strings.Split(secretvars, ",") { secretvar = strings.TrimSpace(secretvar) // get the value from env diff --git a/generator/writer.go b/generator/writer.go index 6db0bba..b661ddd 100644 --- a/generator/writer.go +++ b/generator/writer.go @@ -16,7 +16,10 @@ import ( "gopkg.in/yaml.v3" ) -type HelmFile interface{} +type HelmFile interface { + GetType() string + GetPathRessource() string +} type HelmFileGenerator chan HelmFile var PrefixRE = regexp.MustCompile(`\{\{.*\}\}-?`) @@ -179,7 +182,15 @@ func Generate(p *compose.Parser, katernayVersion, appName, appVersion, chartVers case *helm.ConfigMap, *helm.Secret: // there could be several files, so let's force the filename - name := c.(helm.Named).Name() + name := c.(helm.Named).Name() + "-" + c.GetType() + suffix := c.GetPathRessource() + if suffix != "" { + charToRemove := []string{"/", ".", " "} + for _, char := range charToRemove { + suffix = strings.Replace(suffix, char, "-", -1) + } + } + name += suffix name = PrefixRE.ReplaceAllString(name, "") writers.BuildConfigMap(c, kind, n, name, templatesDir) diff --git a/generator/writers/configmap.go b/generator/writers/configmap.go index 846dabc..d045f1d 100644 --- a/generator/writers/configmap.go +++ b/generator/writers/configmap.go @@ -9,7 +9,7 @@ import ( // BuildConfigMap writes the configMap. func BuildConfigMap(c interface{}, kind, servicename, name, templatesDir string) { - fname := filepath.Join(templatesDir, servicename+"."+name+"."+kind+".yaml") + fname := filepath.Join(templatesDir, name+"."+kind+".yaml") fp, _ := os.Create(fname) enc := yaml.NewEncoder(fp) enc.SetIndent(IndentSize) diff --git a/generator/writers/ingress.go b/generator/writers/ingress.go index be7b4bd..fbfdc60 100644 --- a/generator/writers/ingress.go +++ b/generator/writers/ingress.go @@ -59,6 +59,15 @@ func BuildIngress(ingress *helm.Ingress, name, templatesDir string) { l = apiVersion } + // add annotations linked to the Values + if strings.Contains(l, "annotations:") { + n := CountSpaces(l) + IndentSize + l += "\n" + strings.Repeat(" ", n) + "{{- range $k, $v := .Values.__name__.ingress.annotations }}\n" + l += strings.Repeat(" ", n) + "{{ $k }}: {{ $v }}\n" + l += strings.Repeat(" ", n) + "{{- end }}" + l = strings.ReplaceAll(l, "__name__", name) + } + // pathTyype is ony for 1.19+ if strings.Contains(l, "pathType:") { n := CountSpaces(l) diff --git a/helm/configAndSecretMap.go b/helm/configAndSecretMap.go index b319257..86ff0b7 100644 --- a/helm/configAndSecretMap.go +++ b/helm/configAndSecretMap.go @@ -21,12 +21,15 @@ type ConfigMap struct { } // NewConfigMap returns a new initialzed ConfigMap. -func NewConfigMap(name string) *ConfigMap { +func NewConfigMap(name, path string) *ConfigMap { base := NewBase() base.ApiVersion = "v1" base.Kind = "ConfigMap" base.Metadata.Name = ReleaseNameTpl + "-" + name base.Metadata.Labels[K+"/component"] = name + if path != "" { + base.Metadata.Labels[K+"/path"] = path + } return &ConfigMap{ K8sBase: base, Data: make(map[string]string), @@ -72,12 +75,15 @@ type Secret struct { } // NewSecret returns a new initialzed Secret. -func NewSecret(name string) *Secret { +func NewSecret(name, path string) *Secret { base := NewBase() base.ApiVersion = "v1" base.Kind = "Secret" base.Metadata.Name = ReleaseNameTpl + "-" + name base.Metadata.Labels[K+"/component"] = name + if path != "" { + base.Metadata.Labels[K+"/path"] = path + } return &Secret{ K8sBase: base, Data: make(map[string]string), diff --git a/helm/container.go b/helm/container.go index f202a0c..05441fa 100644 --- a/helm/container.go +++ b/helm/container.go @@ -38,7 +38,6 @@ func NewContainer(name, image string, environment types.MappingWithEquals, label container := &Container{ Image: image, Name: name, - Env: make([]*Value, len(environment)), EnvFrom: make([]map[string]map[string]string, 0), } diff --git a/helm/k8sbase.go b/helm/k8sbase.go index 81a8b42..df95877 100644 --- a/helm/k8sbase.go +++ b/helm/k8sbase.go @@ -4,6 +4,7 @@ import ( "crypto/sha1" "fmt" "io/ioutil" + "strings" ) // Metadata is the metadata for a kubernetes object. @@ -34,7 +35,7 @@ func NewBase() *K8sBase { Metadata: NewMetadata(), } // add some information of the build - b.Metadata.Labels[K+"/project"] = GetProjectName() + b.Metadata.Labels[K+"/project"] = "{{ .Chart.Name }}" b.Metadata.Labels[K+"/release"] = ReleaseNameTpl b.Metadata.Annotations[K+"/version"] = Version return b @@ -56,3 +57,17 @@ func (k *K8sBase) Get() string { func (k *K8sBase) Name() string { return k.Metadata.Name } + +func (k *K8sBase) GetType() string { + if n, ok := k.Metadata.Labels[K+"/type"]; ok { + return n + } + return strings.ToLower(k.Kind) +} + +func (k *K8sBase) GetPathRessource() string { + if p, ok := k.Metadata.Labels[K+"/path"]; ok { + return p + } + return "" +}