From 4f0298c0a982a088c2a759a77b09c7e2c9e6b6a8 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Tue, 26 Nov 2024 16:09:12 +0100 Subject: [PATCH 1/3] test(utils): Add some tests --- generator/utils_test.go | 99 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 generator/utils_test.go diff --git a/generator/utils_test.go b/generator/utils_test.go new file mode 100644 index 0000000..f798810 --- /dev/null +++ b/generator/utils_test.go @@ -0,0 +1,99 @@ +package generator + +import ( + "fmt" + "katenary/generator/labels" + "os" + "path/filepath" + "testing" + + "github.com/compose-spec/compose-go/cli" +) + +func TestSplitPorts(t *testing.T) { + composeFileContent := ` +services: + foo: + image: nginx:latest + labels: + %[1]s/ports: 80,443 +` + composeFileContent = fmt.Sprintf(composeFileContent, labels.KatenaryLabelPrefix) + tmpDir, err := os.MkdirTemp("", "katenary-test-override") + if err != nil { + t.Fatalf(err.Error()) + } + composeFile := filepath.Join(tmpDir, "compose.yaml") + + os.MkdirAll(tmpDir, 0755) + if err := os.WriteFile(composeFile, []byte(composeFileContent), 0644); err != nil { + t.Log(err) + } + defer os.RemoveAll(tmpDir) + + // chand dir to this directory + os.Chdir(tmpDir) + options, _ := cli.NewProjectOptions(nil, + cli.WithWorkingDirectory(tmpDir), + cli.WithDefaultConfigPath, + ) + project, err := cli.ProjectFromOptions(options) + if err := fixPorts(&project.Services[0]); err != nil { + t.Errorf("Expected no error, got %s", err) + } + found := 0 + for _, p := range project.Services[0].Ports { + switch p.Target { + case 80, 443: + found++ + } + } + if found != 2 { + t.Errorf("Expected 2 ports, got %d", found) + } +} + +func TestSplitPortsWithDefault(t *testing.T) { + composeFileContent := ` +services: + foo: + image: nginx:latest + ports: + - 8080 + labels: + %[1]s/ports: 80,443 +` + composeFileContent = fmt.Sprintf(composeFileContent, labels.KatenaryLabelPrefix) + tmpDir, err := os.MkdirTemp("", "katenary-test-override") + if err != nil { + t.Fatalf(err.Error()) + } + composeFile := filepath.Join(tmpDir, "compose.yaml") + + os.MkdirAll(tmpDir, 0755) + if err := os.WriteFile(composeFile, []byte(composeFileContent), 0644); err != nil { + t.Log(err) + } + defer os.RemoveAll(tmpDir) + + // chand dir to this directory + os.Chdir(tmpDir) + options, _ := cli.NewProjectOptions(nil, + cli.WithWorkingDirectory(tmpDir), + cli.WithDefaultConfigPath, + ) + project, err := cli.ProjectFromOptions(options) + if err := fixPorts(&project.Services[0]); err != nil { + t.Errorf("Expected no error, got %s", err) + } + found := 0 + for _, p := range project.Services[0].Ports { + switch p.Target { + case 80, 443, 8080: + found++ + } + } + if found != 3 { + t.Errorf("Expected 3 ports, got %d", found) + } +} From 3b4dade699eb4e42982d2413b43260c28cbbea24 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Tue, 26 Nov 2024 16:11:12 +0100 Subject: [PATCH 2/3] chore(label): new label "values-from" This labels allow to use some environment variables from another service and use the configMap / secret instead of the original value. This is useful to avoid duplication of values for several variables. --- generator/chart.go | 83 +++++++++++ generator/chart_test.go | 157 +++++++++++++++++++++ generator/deployment.go | 2 + generator/generator.go | 14 ++ generator/katenaryfile/main.go | 2 + generator/labels/katenaryLabels.go | 1 + generator/labels/katenaryLabelsDoc.yaml | 32 +++++ generator/labels/labelStructs/valueFrom.go | 13 ++ 8 files changed, 304 insertions(+) create mode 100644 generator/chart_test.go create mode 100644 generator/labels/labelStructs/valueFrom.go diff --git a/generator/chart.go b/generator/chart.go index 5482bdf..9d4c564 100644 --- a/generator/chart.go +++ b/generator/chart.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/compose-spec/compose-go/types" + corev1 "k8s.io/api/core/v1" ) // ChartTemplate is a template of a chart. It contains the content of the template and the name of the service. @@ -342,3 +343,85 @@ func (chart *HelmChart) setSharedConf(service types.ServiceConfig, deployments m addConfigMapToService(service.Name, fromservice, chart.Name, target) } } + +// setEnvironmentValuesFrom sets the environment values from another service. +func (chart *HelmChart) setEnvironmentValuesFrom(service types.ServiceConfig, deployments map[string]*Deployment) { + if _, ok := service.Labels[labels.LabelValueFrom]; !ok { + return + } + mapping, err := labelStructs.GetValueFrom(service.Labels[labels.LabelValueFrom]) + if err != nil { + log.Fatal("error unmarshaling values-from label:", err) + } + + findDeployment := func(name string) *Deployment { + for _, dep := range deployments { + if dep.service.Name == name { + return dep + } + } + return nil + } + + // each mapping key is the environment, and the value is serivename.variable name + for env, from := range *mapping { + // find the deployment that has the variable + depName := strings.Split(from, ".") + dep := findDeployment(depName[0]) + target := findDeployment(service.Name) + if dep == nil || target == nil { + log.Fatalf("deployment %s or %s not found", depName[0], service.Name) + } + container, index := utils.GetContainerByName(target.service.Name, target.Spec.Template.Spec.Containers) + if container == nil { + log.Fatalf("Container %s not found", target.GetName()) + } + reourceName := fmt.Sprintf(`{{ include "%s.fullname" . }}-%s`, chart.Name, depName[0]) + // add environment with from + + // is it a secret? + isSecret := false + secrets, err := labelStructs.SecretsFrom(dep.service.Labels[labels.LabelSecrets]) + if err == nil { + for _, secret := range secrets { + if secret == depName[1] { + isSecret = true + break + } + } + } + + if !isSecret { + container.Env = append(container.Env, corev1.EnvVar{ + Name: env, + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: reourceName, + }, + Key: depName[1], + }, + }, + }) + } else { + container.Env = append(container.Env, corev1.EnvVar{ + Name: env, + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: reourceName, + }, + Key: depName[1], + }, + }, + }) + } + // the environment is bound, so we shouldn't add it to the values.yaml or in any other place + delete(service.Environment, env) + // also, remove the values + target.boundEnvVar = append(target.boundEnvVar, env) + // and save the container + target.Spec.Template.Spec.Containers[index] = *container + + } +} diff --git a/generator/chart_test.go b/generator/chart_test.go new file mode 100644 index 0000000..dde6a54 --- /dev/null +++ b/generator/chart_test.go @@ -0,0 +1,157 @@ +package generator + +import ( + "fmt" + "katenary/generator/labels" + "os" + "strings" + "testing" + + appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +func TestValuesFrom(t *testing.T) { + composeFile := ` +services: + aa: + image: nginx:latest + environment: + AA_USER: foo + bb: + image: nginx:latest + labels: + %[1]s/values-from: |- + BB_USER: aa.USER +` + composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := internalCompileTest(t, "-s", "templates/aa/configmap.yaml") + configMap := v1.ConfigMap{} + if err := yaml.Unmarshal([]byte(output), &configMap); err != nil { + t.Errorf(unmarshalError, err) + } + data := configMap.Data + if v, ok := data["AA_USER"]; !ok || v != "foo" { + t.Errorf("Expected AA_USER to be foo, got %s", v) + } +} + +func TestValuesFromCopy(t *testing.T) { + composeFile := ` +services: + aa: + image: nginx:latest + environment: + AA_USER: foo + bb: + image: nginx:latest + labels: + %[1]s/values-from: |- + BB_USER: aa.AA_USER +` + composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := internalCompileTest(t, "-s", "templates/bb/deployment.yaml") + dep := appsv1.Deployment{} + if err := yaml.Unmarshal([]byte(output), &dep); err != nil { + t.Errorf(unmarshalError, err) + } + containers := dep.Spec.Template.Spec.Containers + environment := containers[0].Env[0] + + envFrom := environment.ValueFrom.ConfigMapKeyRef + if envFrom.Key != "AA_USER" { + t.Errorf("Expected AA_USER, got %s", envFrom.Key) + } + if !strings.Contains(envFrom.Name, "aa") { + t.Errorf("Expected aa, got %s", envFrom.Name) + } +} + +func TestValuesFromSecret(t *testing.T) { + composeFile := ` +services: + aa: + image: nginx:latest + environment: + AA_USER: foo + labels: + %[1]s/secrets: |- + - AA_USER + bb: + image: nginx:latest + labels: + %[1]s/values-from: |- + BB_USER: aa.AA_USER +` + composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := internalCompileTest(t, "-s", "templates/bb/deployment.yaml") + dep := appsv1.Deployment{} + if err := yaml.Unmarshal([]byte(output), &dep); err != nil { + t.Errorf(unmarshalError, err) + } + containers := dep.Spec.Template.Spec.Containers + environment := containers[0].Env[0] + + envFrom := environment.ValueFrom.SecretKeyRef + if envFrom.Key != "AA_USER" { + t.Errorf("Expected AA_USER, got %s", envFrom.Key) + } + if !strings.Contains(envFrom.Name, "aa") { + t.Errorf("Expected aa, got %s", envFrom.Name) + } +} + +func TestEnvFrom(t *testing.T) { + composeFile := ` +services: + web: + image: nginx:1.29 + environment: + Foo: bar + BAZ: qux + db: + image: postgres + labels: + %[1]s/env-from: |- + - web +` + composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := internalCompileTest(t, "-s", "templates/db/deployment.yaml") + dep := appsv1.Deployment{} + if err := yaml.Unmarshal([]byte(output), &dep); err != nil { + t.Errorf(unmarshalError, err) + } + envFrom := dep.Spec.Template.Spec.Containers[0].EnvFrom + if len(envFrom) != 1 { + t.Fatalf("Expected 1 envFrom, got %d", len(envFrom)) + } +} diff --git a/generator/deployment.go b/generator/deployment.go index 51f0a61..c05de83 100644 --- a/generator/deployment.go +++ b/generator/deployment.go @@ -40,6 +40,7 @@ type Deployment struct { defaultTag string `yaml:"-"` isMainApp bool `yaml:"-"` exchangesVolumes map[string]*labelStructs.ExchangeVolume `yaml:"-"` + boundEnvVar []string `yaml:"-"` // environement to remove } // NewDeployment creates a new Deployment from a compose service. The appName is the name of the application taken from the project name. @@ -94,6 +95,7 @@ func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment { configMaps: make(map[string]*ConfigMapMount), volumeMap: make(map[string]string), exchangesVolumes: map[string]*labelStructs.ExchangeVolume{}, + boundEnvVar: []string{}, } // add containers diff --git a/generator/generator.go b/generator/generator.go index a96fb5f..bc16941 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -113,6 +113,10 @@ func Generate(project *types.Project) (*HelmChart, error) { } } } + // it's now time to get "value-from", before makeing the secrets and configmaps! + for _, s := range project.Services { + chart.setEnvironmentValuesFrom(s, deployments) + } // generate configmaps with environment variables chart.generateConfigMapsAndSecrets(project) @@ -123,6 +127,16 @@ func Generate(project *types.Project) (*HelmChart, error) { chart.setSharedConf(s, deployments) } + // remove all "boundEnv" from the values + for _, d := range deployments { + if len(d.boundEnvVar) == 0 { + continue + } + for _, e := range d.boundEnvVar { + delete(chart.Values[d.service.Name].(*Value).Environment, e) + } + } + // generate yaml files for _, d := range deployments { y, err := d.Yaml() diff --git a/generator/katenaryfile/main.go b/generator/katenaryfile/main.go index 789855d..312d747 100644 --- a/generator/katenaryfile/main.go +++ b/generator/katenaryfile/main.go @@ -40,6 +40,7 @@ type Service struct { CronJob *labelStructs.CronJob `json:"cron-job,omitempty" jsonschema:"title=Cron Job,description=Cron Job configuration"` EnvFrom *labelStructs.EnvFrom `json:"env-from,omitempty" jsonschema:"title=Env From,description=Inject environment variables from another service"` ExchangeVolumes []*labelStructs.ExchangeVolume `json:"exchange-volumes,omitempty" jsonschema:"title=Exchange Volumes,description=Exchange volumes between services"` + ValuesFrom *labelStructs.ValueFrom `json:"values-from,omitempty" jsonschema:"title=Values From,description=Inject values from another service (secret or configmap environment variables)"` } // OverrideWithConfig overrides the project with the katenary.yaml file. It @@ -91,6 +92,7 @@ func OverrideWithConfig(project *types.Project) { getLabelContent(s.CronJob, &project.Services[i], labels.LabelCronJob) getLabelContent(s.EnvFrom, &project.Services[i], labels.LabelEnvFrom) getLabelContent(s.ExchangeVolumes, &project.Services[i], labels.LabelExchangeVolume) + getLabelContent(s.ValuesFrom, &project.Services[i], labels.LabelValueFrom) } } fmt.Println(utils.IconInfo, "Katenary file loaded successfully, the services are now configured.") diff --git a/generator/labels/katenaryLabels.go b/generator/labels/katenaryLabels.go index 0bc0494..7125f5b 100644 --- a/generator/labels/katenaryLabels.go +++ b/generator/labels/katenaryLabels.go @@ -33,6 +33,7 @@ const ( LabelCronJob Label = KatenaryLabelPrefix + "/cronjob" LabelEnvFrom Label = KatenaryLabelPrefix + "/env-from" LabelExchangeVolume Label = KatenaryLabelPrefix + "/exchange-volumes" + LabelValueFrom Label = KatenaryLabelPrefix + "/values-from" ) var ( diff --git a/generator/labels/katenaryLabelsDoc.yaml b/generator/labels/katenaryLabelsDoc.yaml index 8a922d7..87f2d01 100644 --- a/generator/labels/katenaryLabelsDoc.yaml +++ b/generator/labels/katenaryLabelsDoc.yaml @@ -321,4 +321,36 @@ mountPath: /opt init: cp -ra /var/www/html/* /opt +"values-from": + short: "Add values from another service." + long: |- + This label allows adding values from another service to the current service. + It avoid duplicating values, environment or secrets that should be the same. + + The key is the value to be added, and the value is the "key" to fetch in the + form `service_name.environment_name`. + + type: "map[string]string" + example: |- + database: + image: mariadb:10.5 + environment: + MARIADB_USER: myuser + MARIADB_PASSWORD: mypassword + labels: + # it can be a secret + {{ .KatenaryPrefix }}/secrets: |- + - DB_PASSWORD + php: + image: php:7.4-fpm + environment: + # it's duplicated in docker / podman + DB_USER: myuser + DB_PASSWORD: mypassword + labels: + # removes the duplicated, use the configMap and secrets from "database" + {{ .KatenaryPrefix }}/values-from: |- + DB_USER: database.MARIADB_USER + DB_PASSWORD: database.MARIADB_PASSWORD + # vim: ft=gotmpl.yaml diff --git a/generator/labels/labelStructs/valueFrom.go b/generator/labels/labelStructs/valueFrom.go new file mode 100644 index 0000000..9ad5712 --- /dev/null +++ b/generator/labels/labelStructs/valueFrom.go @@ -0,0 +1,13 @@ +package labelStructs + +import "gopkg.in/yaml.v3" + +type ValueFrom map[string]string + +func GetValueFrom(data string) (*ValueFrom, error) { + vf := ValueFrom{} + if err := yaml.Unmarshal([]byte(data), &vf); err != nil { + return nil, err + } + return &vf, nil +} From 9181c389d4249f46bda4f16bbbdf3b9489eb30f0 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Tue, 26 Nov 2024 16:11:46 +0100 Subject: [PATCH 3/3] doc(refresh): Refresh documentation --- doc/docs/labels.md | 39 ++++++++++ doc/docs/packages/generator.md | 71 ++++++++----------- doc/docs/packages/generator/katenaryfile.md | 7 +- doc/docs/packages/generator/labels.md | 15 ++-- .../packages/generator/labels/labelStructs.md | 30 ++++++-- doc/docs/packages/utils.md | 40 +++-------- 6 files changed, 117 insertions(+), 85 deletions(-) diff --git a/doc/docs/labels.md b/doc/docs/labels.md index 85ad668..d361eea 100644 --- a/doc/docs/labels.md +++ b/doc/docs/labels.md @@ -24,6 +24,7 @@ Katenary will try to Unmarshal these labels. | `katenary.v3/same-pod` | Move the same-pod deployment to the target deployment. | string | | `katenary.v3/secrets` | Env vars to be set as secrets. | list of string | | `katenary.v3/values` | Environment variables to be added to the values.yaml | list of string or map | +| `katenary.v3/values-from` | Add values from another service. | map[string]string | @@ -438,4 +439,42 @@ labels: ``` +### katenary.v3/values-from + +Add values from another service. + +**Type**: `map[string]string` + +This label allows adding values from another service to the current service. +It avoid duplicating values, environment or secrets that should be the same. + +The key is the value to be added, and the value is the "key" to fetch in the +form `service_name.environment_name`. + +**Example:** + +```yaml +database: + image: mariadb:10.5 + environment: + MARIADB_USER: myuser + MARIADB_PASSWORD: mypassword + labels: + # it can be a secret + katenary.v3/secrets: |- + - DB_PASSWORD +php: + image: php:7.4-fpm + environment: + # it's duplicated in docker / podman + DB_USER: myuser + DB_PASSWORD: mypassword + labels: + # removes the duplicated, use the configMap and secrets from "database" + katenary.v3/values-from: |- + DB_USER: database.MARIADB_USER + DB_PASSWORD: database.MARIADB_PASSWORD +``` + + diff --git a/doc/docs/packages/generator.md b/doc/docs/packages/generator.md index 21fd533..c918312 100644 --- a/doc/docs/packages/generator.md +++ b/doc/docs/packages/generator.md @@ -8,7 +8,7 @@ import "katenary/generator" The generator package generates kubernetes objects from a "compose" file and transforms them into a helm chart. -The generator package is the core of katenary. It is responsible for generating kubernetes objects from a compose file and transforming them into a helm chart. Convertion manipulates Yaml representation of kubernetes object to add conditions, labels, annotations, etc. to the objects. It also create the values to be set to the values.yaml file. +The generator package is the core of katenary. It is responsible for generating kubernetes objects from a compose file and transforming them into a helm chart. Conversion manipulates Yaml representation of kubernetes object to add conditions, labels, annotations, etc. to the objects. It also create the values to be set to the values.yaml file. The generate.Convert\(\) create an HelmChart object and call "Generate\(\)" method to convert from a compose file to a helm chart. It saves the helm chart in the given directory. @@ -98,7 +98,7 @@ func UnWrapTPL(in []byte) []byte UnWrapTPL removes the line wrapping from a template. -## type [ChartTemplate]() +## type [ChartTemplate]() ChartTemplate is a template of a chart. It contains the content of the template and the name of the service. This is used internally to generate the templates. @@ -110,7 +110,7 @@ type ChartTemplate struct { ``` -## type [ConfigMap]() +## type [ConfigMap]() ConfigMap is a kubernetes ConfigMap. Implements the DataMap interface. @@ -122,7 +122,7 @@ type ConfigMap struct { ``` -### func [NewConfigMap]() +### func [NewConfigMap]() ```go func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *ConfigMap @@ -131,7 +131,7 @@ func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *Co NewConfigMap creates a new ConfigMap from a compose service. The appName is the name of the application taken from the project name. The ConfigMap is filled by environment variables and labels "map\-env". -### func [NewConfigMapFromDirectory]() +### func [NewConfigMapFromDirectory]() ```go func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string) *ConfigMap @@ -140,7 +140,7 @@ func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the file or directory. If the path is a directory, all files in the directory are added to the ConfigMap. Each subdirectory are ignored. Note that the Generate\(\) function will create the subdirectories ConfigMaps. -### func \(\*ConfigMap\) [AddData]() +### func \(\*ConfigMap\) [AddData]() ```go func (c *ConfigMap) AddData(key, value string) @@ -149,7 +149,7 @@ func (c *ConfigMap) AddData(key, value string) AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists. -### func \(\*ConfigMap\) [AppendDir]() +### func \(\*ConfigMap\) [AppendDir]() ```go func (c *ConfigMap) AppendDir(path string) @@ -158,7 +158,7 @@ func (c *ConfigMap) AppendDir(path string) AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory, you need to call this function for each subdirectory. -### func \(\*ConfigMap\) [AppendFile]() +### func \(\*ConfigMap\) [AppendFile]() ```go func (c *ConfigMap) AppendFile(path string) @@ -167,7 +167,7 @@ func (c *ConfigMap) AppendFile(path string) -### func \(\*ConfigMap\) [Filename]() +### func \(\*ConfigMap\) [Filename]() ```go func (c *ConfigMap) Filename() string @@ -176,7 +176,7 @@ func (c *ConfigMap) Filename() string Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path. -### func \(\*ConfigMap\) [SetData]() +### func \(\*ConfigMap\) [SetData]() ```go func (c *ConfigMap) SetData(data map[string]string) @@ -185,7 +185,7 @@ func (c *ConfigMap) SetData(data map[string]string) SetData sets the data of the configmap. It replaces the entire data. -### func \(\*ConfigMap\) [Yaml]() +### func \(\*ConfigMap\) [Yaml]() ```go func (c *ConfigMap) Yaml() ([]byte, error) @@ -205,7 +205,7 @@ type ConfigMapMount struct { ``` -## type [ConvertOptions]() +## type [ConvertOptions]() ConvertOptions are the options to convert a compose project to a helm chart. @@ -282,17 +282,8 @@ type DataMap interface { } ``` - -### func [NewFileMap]() - -```go -func NewFileMap(service types.ServiceConfig, appName, kind string) DataMap -``` - -NewFileMap creates a new DataMap from a compose service. The appName is the name of the application taken from the project name. - -## type [Deployment]() +## type [Deployment]() Deployment is a kubernetes Deployment. @@ -304,7 +295,7 @@ type Deployment struct { ``` -### func [NewDeployment]() +### func [NewDeployment]() ```go func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment @@ -313,7 +304,7 @@ func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment NewDeployment creates a new Deployment from a compose service. The appName is the name of the application taken from the project name. It also creates the Values map that will be used to create the values.yaml file. -### func \(\*Deployment\) [AddContainer]() +### func \(\*Deployment\) [AddContainer]() ```go func (d *Deployment) AddContainer(service types.ServiceConfig) @@ -322,7 +313,7 @@ func (d *Deployment) AddContainer(service types.ServiceConfig) AddContainer adds a container to the deployment. -### func \(\*Deployment\) [AddHealthCheck]() +### func \(\*Deployment\) [AddHealthCheck]() ```go func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *corev1.Container) @@ -331,7 +322,7 @@ func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *core -### func \(\*Deployment\) [AddIngress]() +### func \(\*Deployment\) [AddIngress]() ```go func (d *Deployment) AddIngress(service types.ServiceConfig, appName string) *Ingress @@ -340,7 +331,7 @@ func (d *Deployment) AddIngress(service types.ServiceConfig, appName string) *In AddIngress adds an ingress to the deployment. It creates the ingress object. -### func \(\*Deployment\) [AddLegacyVolume]() +### func \(\*Deployment\) [AddLegacyVolume]() ```go func (d *Deployment) AddLegacyVolume(name, kind string) @@ -349,7 +340,7 @@ func (d *Deployment) AddLegacyVolume(name, kind string) -### func \(\*Deployment\) [AddVolumes]() +### func \(\*Deployment\) [AddVolumes]() ```go func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) @@ -358,7 +349,7 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) AddVolumes adds a volume to the deployment. It does not create the PVC, it only adds the volumes to the deployment. If the volume is a bind volume it will warn the user that it is not supported yet. -### func \(\*Deployment\) [BindFrom]() +### func \(\*Deployment\) [BindFrom]() ```go func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) @@ -367,7 +358,7 @@ func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) -### func \(\*Deployment\) [BindMapFilesToContainer]() +### func \(\*Deployment\) [BindMapFilesToContainer]() ```go func (d *Deployment) BindMapFilesToContainer(service types.ServiceConfig, secrets []string, appName string) (*corev1.Container, int) @@ -376,7 +367,7 @@ func (d *Deployment) BindMapFilesToContainer(service types.ServiceConfig, secret -### func \(\*Deployment\) [DependsOn]() +### func \(\*Deployment\) [DependsOn]() ```go func (d *Deployment) DependsOn(to *Deployment, servicename string) error @@ -385,7 +376,7 @@ func (d *Deployment) DependsOn(to *Deployment, servicename string) error DependsOn adds a initContainer to the deployment that will wait for the service to be up. -### func \(\*Deployment\) [Filename]() +### func \(\*Deployment\) [Filename]() ```go func (d *Deployment) Filename() string @@ -394,7 +385,7 @@ func (d *Deployment) Filename() string Filename returns the filename of the deployment. -### func \(\*Deployment\) [MountExchangeVolumes]() +### func \(\*Deployment\) [MountExchangeVolumes]() ```go func (d *Deployment) MountExchangeVolumes() @@ -403,7 +394,7 @@ func (d *Deployment) MountExchangeVolumes() -### func \(\*Deployment\) [SetEnvFrom]() +### func \(\*Deployment\) [SetEnvFrom]() ```go func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string, samePod ...bool) @@ -412,7 +403,7 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string, sam SetEnvFrom sets the environment variables to a configmap. The configmap is created. -### func \(\*Deployment\) [Yaml]() +### func \(\*Deployment\) [Yaml]() ```go func (d *Deployment) Yaml() ([]byte, error) @@ -439,9 +430,9 @@ const ( ``` -## type [HelmChart]() +## type [HelmChart]() -HelmChart is a Helm Chart representation. It contains all the tempaltes, values, versions, helpers... +HelmChart is a Helm Chart representation. It contains all the templates, values, versions, helpers... ```go type HelmChart struct { @@ -482,7 +473,7 @@ The Generate function will create the HelmChart object this way: - Merge the same\-pod services. -### func [NewChart]() +### func [NewChart]() ```go func NewChart(name string) *HelmChart @@ -491,7 +482,7 @@ func NewChart(name string) *HelmChart NewChart creates a new empty chart with the given name. -### func \(\*HelmChart\) [SaveTemplates]() +### func \(\*HelmChart\) [SaveTemplates]() ```go func (chart *HelmChart) SaveTemplates(templateDir string) @@ -813,7 +804,7 @@ type TLS struct { ## type [Value]() -Value will be saved in values.yaml. It contains configuraiton for all deployment and services. +Value will be saved in values.yaml. It contains configuration for all deployment and services. ```go type Value struct { diff --git a/doc/docs/packages/generator/katenaryfile.md b/doc/docs/packages/generator/katenaryfile.md index 5e80f85..02ade60 100644 --- a/doc/docs/packages/generator/katenaryfile.md +++ b/doc/docs/packages/generator/katenaryfile.md @@ -12,7 +12,7 @@ A katenary file, named "katenary.yml" or "katenary.yaml", is a file where you ca Formely, the file describe the same structure as in labels, and so that can be validated and completed by LSP. It also ease the use of katenary. -## func [GenerateSchema]() +## func [GenerateSchema]() ```go func GenerateSchema() string @@ -21,7 +21,7 @@ func GenerateSchema() string GenerateSchema generates the schema for the katenary.yaml file. -## func [OverrideWithConfig]() +## func [OverrideWithConfig]() ```go func OverrideWithConfig(project *types.Project) @@ -30,7 +30,7 @@ func OverrideWithConfig(project *types.Project) OverrideWithConfig overrides the project with the katenary.yaml file. It will set the labels of the services with the values from the katenary.yaml file. It work in memory, so it will not modify the original project. -## type [Service]() +## type [Service]() Service is a struct that contains the service configuration for katenary @@ -51,6 +51,7 @@ type Service struct { CronJob *labelStructs.CronJob `json:"cron-job,omitempty" jsonschema:"title=Cron Job,description=Cron Job configuration"` EnvFrom *labelStructs.EnvFrom `json:"env-from,omitempty" jsonschema:"title=Env From,description=Inject environment variables from another service"` ExchangeVolumes []*labelStructs.ExchangeVolume `json:"exchange-volumes,omitempty" jsonschema:"title=Exchange Volumes,description=Exchange volumes between services"` + ValuesFrom *labelStructs.ValueFrom `json:"values-from,omitempty" jsonschema:"title=Values From,description=Inject values from another service (secret or configmap environment variables)"` } ``` diff --git a/doc/docs/packages/generator/labels.md b/doc/docs/packages/generator/labels.md index 8d7b098..7e9bfbc 100644 --- a/doc/docs/packages/generator/labels.md +++ b/doc/docs/packages/generator/labels.md @@ -15,7 +15,7 @@ const KatenaryLabelPrefix = "katenary.v3" ``` -## func [GetLabelHelp]() +## func [GetLabelHelp]() ```go func GetLabelHelp(asMarkdown bool) string @@ -24,7 +24,7 @@ func GetLabelHelp(asMarkdown bool) string Generate the help for the labels. -## func [GetLabelHelpFor]() +## func [GetLabelHelpFor]() ```go func GetLabelHelpFor(labelname string, asMarkdown bool) string @@ -33,7 +33,7 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string GetLabelHelpFor returns the help for a specific label. -## func [GetLabelNames]() +## func [GetLabelNames]() ```go func GetLabelNames() []string @@ -42,7 +42,7 @@ func GetLabelNames() []string GetLabelNames returns a sorted list of all katenary label names. -## func [Prefix]() +## func [Prefix]() ```go func Prefix() string @@ -51,7 +51,7 @@ func Prefix() string -## type [Help]() +## type [Help]() Help is the documentation of a label. @@ -65,7 +65,7 @@ type Help struct { ``` -## type [Label]() +## type [Label]() Label is a katenary label to find in compose files. @@ -92,11 +92,12 @@ const ( LabelCronJob Label = KatenaryLabelPrefix + "/cronjob" LabelEnvFrom Label = KatenaryLabelPrefix + "/env-from" LabelExchangeVolume Label = KatenaryLabelPrefix + "/exchange-volumes" + LabelValueFrom Label = KatenaryLabelPrefix + "/values-from" ) ``` -### func [LabelName]() +### func [LabelName]() ```go func LabelName(name string) Label diff --git a/doc/docs/packages/generator/labels/labelStructs.md b/doc/docs/packages/generator/labels/labelStructs.md index b582c3e..3ac1643 100644 --- a/doc/docs/packages/generator/labels/labelStructs.md +++ b/doc/docs/packages/generator/labels/labelStructs.md @@ -135,24 +135,24 @@ func ProbeFrom(data string) (*HealthCheck, error) -## type [Ingress]() +## type [Ingress]() ```go type Ingress struct { - Port *int32 `yaml:"port,omitempty" jsonschema:"nullable" json:"port,omitempty"` + Port *int32 `yaml:"port,omitempty" json:"port,omitempty"` Annotations map[string]string `yaml:"annotations,omitempty" jsonschema:"nullable" json:"annotations,omitempty"` Hostname string `yaml:"hostname" json:"hostname,omitempty"` - Path string `yaml:"path" json:"path,omitempty"` - Class string `yaml:"class" json:"class,omitempty" jsonschema:"default:-"` + Path *string `yaml:"path,omitempty" json:"path,omitempty"` + Class *string `yaml:"class,omitempty" json:"class,omitempty" jsonschema:"default:-"` Enabled bool `yaml:"enabled" json:"enabled,omitempty"` TLS *TLS `yaml:"tls,omitempty" json:"tls,omitempty"` } ``` -### func [IngressFrom]() +### func [IngressFrom]() ```go func IngressFrom(data string) (*Ingress, error) @@ -215,7 +215,7 @@ func SecretsFrom(data string) (Secrets, error) -## type [TLS]() +## type [TLS]() @@ -225,4 +225,22 @@ type TLS struct { } ``` + +## type [ValueFrom]() + + + +```go +type ValueFrom map[string]string +``` + + +### func [GetValueFrom]() + +```go +func GetValueFrom(data string) (*ValueFrom, error) +``` + + + Generated by [gomarkdoc]() diff --git a/doc/docs/packages/utils.md b/doc/docs/packages/utils.md index da4a994..2f0ad01 100644 --- a/doc/docs/packages/utils.md +++ b/doc/docs/packages/utils.md @@ -8,7 +8,7 @@ import "katenary/utils" Utils package provides some utility functions used in katenary. It defines some constants and functions used in the whole project. -## func [AsResourceName]() +## func [AsResourceName]() ```go func AsResourceName(name string) string @@ -17,7 +17,7 @@ func AsResourceName(name string) string AsResourceName returns a resource name with underscores to respect the kubernetes naming convention. It's the opposite of FixedResourceName. -## func [Confirm]() +## func [Confirm]() ```go func Confirm(question string, icon ...Icon) bool @@ -35,7 +35,7 @@ func CountStartingSpaces(line string) int CountStartingSpaces counts the number of spaces at the beginning of a string. -## func [EncodeBasicYaml]() +## func [EncodeBasicYaml]() ```go func EncodeBasicYaml(data any) ([]byte, error) @@ -44,7 +44,7 @@ func EncodeBasicYaml(data any) ([]byte, error) EncodeBasicYaml encodes a basic yaml from an interface. -## func [FixedResourceName]() +## func [FixedResourceName]() ```go func FixedResourceName(name string) string @@ -53,7 +53,7 @@ func FixedResourceName(name string) string FixedResourceName returns a resource name without underscores to respect the kubernetes naming convention. -## func [GetContainerByName]() +## func [GetContainerByName]() ```go func GetContainerByName(name string, containers []corev1.Container) (*corev1.Container, int) @@ -71,7 +71,7 @@ func GetKind(path string) (kind string) GetKind returns the kind of the resource from the file path. -## func [GetServiceNameByPort]() +## func [GetServiceNameByPort]() ```go func GetServiceNameByPort(port int) string @@ -80,7 +80,7 @@ func GetServiceNameByPort(port int) string GetServiceNameByPort returns the service name for a port. It the service name is not found, it returns an empty string. -## func [GetValuesFromLabel]() +## func [GetValuesFromLabel]() ```go func GetValuesFromLabel(service types.ServiceConfig, LabelValues string) map[string]*EnvConfig @@ -106,17 +106,8 @@ func Int32Ptr(i int32) *int32 Int32Ptr returns a pointer to an int32. - -## func [MapKeys]() - -```go -func MapKeys(m map[string]interface{}) []string -``` - - - -## func [PathToName]() +## func [PathToName]() ```go func PathToName(path string) string @@ -143,7 +134,7 @@ func TplName(serviceName, appname string, suffix ...string) string TplName returns the name of the kubernetes resource as a template string. It is used in the templates and defined in \_helper.tpl file. -## func [TplValue]() +## func [TplValue]() ```go func TplValue(serviceName, variable string, pipes ...string) string @@ -161,7 +152,7 @@ func Warn(msg ...interface{}) Warn prints a warning message -## func [WordWrap]() +## func [WordWrap]() ```go func WordWrap(text string, lineWidth int) string @@ -178,17 +169,8 @@ func Wrap(src, above, below string) string Wrap wraps a string with a string above and below. It will respect the indentation of the src string. - -## func [WrapBytes]() - -```go -func WrapBytes(src, above, below []byte) []byte -``` - -WrapBytes wraps a byte array with a byte array above and below. It will respect the indentation of the src string. - -## type [EnvConfig]() +## type [EnvConfig]() EnvConfig is a struct to hold the description of an environment variable.