Merge pull request #81 from metal3d/develop
Cleanup, re-factorization and allow the use of a katenary.yaml file. Fixing a wrapping string problem. Move the label management in a package.
This commit is contained in:
27
.gitignore
vendored
27
.gitignore
vendored
@@ -1,25 +1,20 @@
|
||||
.venv
|
||||
dist/*
|
||||
.cache/*
|
||||
chart/*
|
||||
*.yaml
|
||||
*.yml
|
||||
!.markdownlint.yaml
|
||||
!generator/*.yaml
|
||||
doc/venv/*
|
||||
!doc/mkdocs.yaml
|
||||
!.readthedocs.yaml
|
||||
./katenary
|
||||
*.env
|
||||
docker-compose*
|
||||
!examples/**/docker-compose*
|
||||
.credentials
|
||||
release.id
|
||||
configs/
|
||||
cover*
|
||||
.sq
|
||||
./katenary
|
||||
.aider*
|
||||
.python_history
|
||||
.bash_history
|
||||
katenary
|
||||
|
||||
.cache/
|
||||
.aider/
|
||||
.config/
|
||||
*/venv
|
||||
|
||||
# local binary
|
||||
./katenary
|
||||
|
||||
# will be treated later
|
||||
/examples/*
|
||||
|
@@ -2,7 +2,7 @@
|
||||
default: true
|
||||
|
||||
MD013: # Line length
|
||||
line_length: 240
|
||||
line_length: 120
|
||||
|
||||
MD010: # Hard tabs
|
||||
code_blocks: false
|
||||
@@ -16,3 +16,6 @@ MD041: false
|
||||
# list indentation
|
||||
MD007:
|
||||
indent: 4
|
||||
|
||||
# no problem using several code blocks styles
|
||||
MD046: false
|
||||
|
3
Makefile
3
Makefile
@@ -169,6 +169,9 @@ tests: test
|
||||
test:
|
||||
@echo -e "\033[1;33mTesting katenary $(VERSION)...\033[0m"
|
||||
go test -coverprofile=cover.out ./...
|
||||
$(MAKE) cover
|
||||
|
||||
cover:
|
||||
go tool cover -func=cover.out | grep "total:"
|
||||
go tool cover -html=cover.out -o cover.html
|
||||
if [ "$(BROWSER)" = "xdg-open" ]; then
|
||||
|
@@ -7,6 +7,8 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator"
|
||||
"katenary/generator/katenaryfile"
|
||||
"katenary/generator/labels"
|
||||
"katenary/utils"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -43,6 +45,7 @@ func buildRootCmd() *cobra.Command {
|
||||
generateConvertCommand(),
|
||||
generateHashComposefilesCommand(),
|
||||
generateLabelHelpCommand(),
|
||||
generateSchemaCommand(),
|
||||
)
|
||||
|
||||
return rootCmd
|
||||
@@ -245,31 +248,31 @@ func generateLabelHelpCommand() *cobra.Command {
|
||||
If no label is specified, the help for all labels is printed.
|
||||
If a label is specified, the help for this label is printed.
|
||||
|
||||
The name of the label must be specified without the prefix ` + generator.Prefix() + `.
|
||||
The name of the label must be specified without the prefix ` + labels.Prefix() + `.
|
||||
|
||||
e.g.
|
||||
kanetary help-labels
|
||||
katenary help-labels ingress
|
||||
katenary help-labels map-env
|
||||
`,
|
||||
ValidArgs: generator.GetLabelNames(),
|
||||
ValidArgs: labels.GetLabelNames(),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) > 0 {
|
||||
fmt.Println(generator.GetLabelHelpFor(args[0], markdown))
|
||||
fmt.Println(labels.GetLabelHelpFor(args[0], markdown))
|
||||
return
|
||||
}
|
||||
if all {
|
||||
// show the help for all labels
|
||||
l := len(generator.GetLabelNames())
|
||||
for i, label := range generator.GetLabelNames() {
|
||||
fmt.Println(generator.GetLabelHelpFor(label, markdown))
|
||||
l := len(labels.GetLabelNames())
|
||||
for i, label := range labels.GetLabelNames() {
|
||||
fmt.Println(labels.GetLabelHelpFor(label, markdown))
|
||||
if !markdown && i < l-1 {
|
||||
fmt.Println(strings.Repeat("-", 80))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
fmt.Println(generator.GetLabelHelp(markdown))
|
||||
fmt.Println(labels.GetLabelHelp(markdown))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -298,3 +301,15 @@ If no composefile is specified, the hash of all composefiles is printed.`,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func generateSchemaCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "schema",
|
||||
Short: "Print the schema of the katenary file",
|
||||
Long: "Generate a schama for katenary.yaml file that can be used to validate the file or to use with yaml LSP to complete and check your configuration.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println(katenaryfile.GenerateSchema())
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ func TestBuildCommand(t *testing.T) {
|
||||
if rootCmd.Use != "katenary" {
|
||||
t.Errorf("Expected rootCmd.Use to be katenary, got %s", rootCmd.Use)
|
||||
}
|
||||
numCommands := 5
|
||||
numCommands := 6
|
||||
if len(rootCmd.Commands()) != numCommands {
|
||||
t.Errorf("Expected %d command, got %d", numCommands, len(rootCmd.Commands()))
|
||||
}
|
||||
|
@@ -1,49 +0,0 @@
|
||||
# cronjobs
|
||||
|
||||
A Helm chart for cronjobs
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
# Standard Helm install
|
||||
$ helm install my-release cronjobs
|
||||
|
||||
# To use a custom namespace and force the creation of the namespace
|
||||
$ helm install my-release --namespace my-namespace --create-namespace cronjobs
|
||||
|
||||
# To use a custom values file
|
||||
$ helm install my-release -f my-values.yaml cronjobs
|
||||
```
|
||||
|
||||
See the [Helm documentation](https://helm.sh/docs/intro/using_helm/) for more information on installing and managing the chart.
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters of the cronjobs chart and their default values.
|
||||
|
||||
| Parameter | Default |
|
||||
| ----------------------------------- | -------------- |
|
||||
| `app.imagePullPolicy` | `IfNotPresent` |
|
||||
| `app.replicas` | `1` |
|
||||
| `app.repository.image` | `nginx` |
|
||||
| `app.repository.tag` | `` |
|
||||
| `backup.cronjob.imagePullPolicy` | `IfNotPresent` |
|
||||
| `backup.cronjob.repository.image` | `alpine` |
|
||||
| `backup.cronjob.repository.tag` | `1` |
|
||||
| `backup.cronjob.schedule` | `@hourly` |
|
||||
| `backup.imagePullPolicy` | `IfNotPresent` |
|
||||
| `backup.replicas` | `1` |
|
||||
| `backup.repository.image` | `alpine` |
|
||||
| `backup.repository.tag` | `1` |
|
||||
| `withrbac.cronjob.imagePullPolicy` | `IfNotPresent` |
|
||||
| `withrbac.cronjob.repository.image` | `busybox` |
|
||||
| `withrbac.cronjob.repository.tag` | `` |
|
||||
| `withrbac.cronjob.schedule` | `@daily` |
|
||||
| `withrbac.imagePullPolicy` | `IfNotPresent` |
|
||||
| `withrbac.replicas` | `1` |
|
||||
| `withrbac.repository.image` | `busybox` |
|
||||
| `withrbac.repository.tag` | `` |
|
||||
|
||||
|
@@ -1,27 +0,0 @@
|
||||
Your release is named {{ .Release.Name }}.
|
||||
|
||||
To learn more about the release, try:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} status {{ .Release.Name }}
|
||||
$ helm -n {{ .Release.Namespace }} get all {{ .Release.Name }}
|
||||
|
||||
To delete the release, run:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} delete {{ .Release.Name }}
|
||||
|
||||
You can see this notes again by running:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} get notes {{ .Release.Name }}
|
||||
|
||||
{{- $count := 0 -}}
|
||||
{{- range $s, $v := .Values -}}
|
||||
{{- if and $v $v.ingress -}}
|
||||
{{- $count = add $count 1 -}}
|
||||
{{- if eq $count 1 }}
|
||||
|
||||
The ingress list is:
|
||||
{{ end }}
|
||||
- {{ $s }}: http://{{ $v.ingress.host }}{{ $v.ingress.path }}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
@@ -1,36 +0,0 @@
|
||||
{{- define "cronjobs.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "cronjobs.name" -}}
|
||||
{{- if .Values.nameOverride -}}
|
||||
{{- .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "cronjobs.labels" -}}
|
||||
{{ include "cronjobs.selectorLabels" .}}
|
||||
{{ if .Chart.Version -}}
|
||||
{{ printf "katenary.v3/chart-version: %s" .Chart.Version }}
|
||||
{{- end }}
|
||||
{{ if .Chart.AppVersion -}}
|
||||
{{ printf "katenary.v3/app-version: %s" .Chart.AppVersion }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "cronjobs.selectorLabels" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{ printf "katenary.v3/name: %s" $name }}
|
||||
{{ printf "katenary.v3/instance: %s" .Release.Name }}
|
||||
{{- end -}}
|
@@ -1,37 +0,0 @@
|
||||
# multidir
|
||||
|
||||
A Helm chart for multidir
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
# Standard Helm install
|
||||
$ helm install my-release multidir
|
||||
|
||||
# To use a custom namespace and force the creation of the namespace
|
||||
$ helm install my-release --namespace my-namespace --create-namespace multidir
|
||||
|
||||
# To use a custom values file
|
||||
$ helm install my-release -f my-values.yaml multidir
|
||||
```
|
||||
|
||||
See the [Helm documentation](https://helm.sh/docs/intro/using_helm/) for more information on installing and managing the chart.
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters of the multidir chart and their default values.
|
||||
|
||||
| Parameter | Default |
|
||||
| ---------------------- | -------------- |
|
||||
| `bar.imagePullPolicy` | `IfNotPresent` |
|
||||
| `bar.replicas` | `1` |
|
||||
| `bar.repository.image` | `alpine` |
|
||||
| `bar.repository.tag` | `` |
|
||||
| `foo.imagePullPolicy` | `IfNotPresent` |
|
||||
| `foo.replicas` | `1` |
|
||||
| `foo.repository.image` | `alpine` |
|
||||
| `foo.repository.tag` | `` |
|
||||
|
||||
|
@@ -1,27 +0,0 @@
|
||||
Your release is named {{ .Release.Name }}.
|
||||
|
||||
To learn more about the release, try:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} status {{ .Release.Name }}
|
||||
$ helm -n {{ .Release.Namespace }} get all {{ .Release.Name }}
|
||||
|
||||
To delete the release, run:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} delete {{ .Release.Name }}
|
||||
|
||||
You can see this notes again by running:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} get notes {{ .Release.Name }}
|
||||
|
||||
{{- $count := 0 -}}
|
||||
{{- range $s, $v := .Values -}}
|
||||
{{- if and $v $v.ingress -}}
|
||||
{{- $count = add $count 1 -}}
|
||||
{{- if eq $count 1 }}
|
||||
|
||||
The ingress list is:
|
||||
{{ end }}
|
||||
- {{ $s }}: http://{{ $v.ingress.host }}{{ $v.ingress.path }}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
@@ -1,36 +0,0 @@
|
||||
{{- define "multidir.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "multidir.name" -}}
|
||||
{{- if .Values.nameOverride -}}
|
||||
{{- .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "multidir.labels" -}}
|
||||
{{ include "multidir.selectorLabels" .}}
|
||||
{{ if .Chart.Version -}}
|
||||
{{ printf "katenary.v3/chart-version: %s" .Chart.Version }}
|
||||
{{- end }}
|
||||
{{ if .Chart.AppVersion -}}
|
||||
{{ printf "katenary.v3/app-version: %s" .Chart.AppVersion }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "multidir.selectorLabels" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{ printf "katenary.v3/name: %s" $name }}
|
||||
{{ printf "katenary.v3/instance: %s" .Release.Name }}
|
||||
{{- end -}}
|
@@ -1 +0,0 @@
|
||||
A file containing configuration here
|
@@ -1,2 +0,0 @@
|
||||
variable: foo
|
||||
example: bar
|
@@ -1,37 +0,0 @@
|
||||
# shareenv
|
||||
|
||||
A Helm chart for shareenv
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
# Standard Helm install
|
||||
$ helm install my-release shareenv
|
||||
|
||||
# To use a custom namespace and force the creation of the namespace
|
||||
$ helm install my-release --namespace my-namespace --create-namespace shareenv
|
||||
|
||||
# To use a custom values file
|
||||
$ helm install my-release -f my-values.yaml shareenv
|
||||
```
|
||||
|
||||
See the [Helm documentation](https://helm.sh/docs/intro/using_helm/) for more information on installing and managing the chart.
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters of the shareenv chart and their default values.
|
||||
|
||||
| Parameter | Default |
|
||||
| ----------------------- | -------------- |
|
||||
| `app1.imagePullPolicy` | `IfNotPresent` |
|
||||
| `app1.replicas` | `1` |
|
||||
| `app1.repository.image` | `nginx` |
|
||||
| `app1.repository.tag` | `1` |
|
||||
| `app2.imagePullPolicy` | `IfNotPresent` |
|
||||
| `app2.replicas` | `1` |
|
||||
| `app2.repository.image` | `nginx` |
|
||||
| `app2.repository.tag` | `1` |
|
||||
|
||||
|
@@ -1,27 +0,0 @@
|
||||
Your release is named {{ .Release.Name }}.
|
||||
|
||||
To learn more about the release, try:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} status {{ .Release.Name }}
|
||||
$ helm -n {{ .Release.Namespace }} get all {{ .Release.Name }}
|
||||
|
||||
To delete the release, run:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} delete {{ .Release.Name }}
|
||||
|
||||
You can see this notes again by running:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} get notes {{ .Release.Name }}
|
||||
|
||||
{{- $count := 0 -}}
|
||||
{{- range $s, $v := .Values -}}
|
||||
{{- if and $v $v.ingress -}}
|
||||
{{- $count = add $count 1 -}}
|
||||
{{- if eq $count 1 }}
|
||||
|
||||
The ingress list is:
|
||||
{{ end }}
|
||||
- {{ $s }}: http://{{ $v.ingress.host }}{{ $v.ingress.path }}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
@@ -1,36 +0,0 @@
|
||||
{{- define "shareenv.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "shareenv.name" -}}
|
||||
{{- if .Values.nameOverride -}}
|
||||
{{- .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "shareenv.labels" -}}
|
||||
{{ include "shareenv.selectorLabels" .}}
|
||||
{{ if .Chart.Version -}}
|
||||
{{ printf "katenary.v3/chart-version: %s" .Chart.Version }}
|
||||
{{- end }}
|
||||
{{ if .Chart.AppVersion -}}
|
||||
{{ printf "katenary.v3/app-version: %s" .Chart.AppVersion }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "shareenv.selectorLabels" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{ printf "katenary.v3/name: %s" $name }}
|
||||
{{ printf "katenary.v3/instance: %s" .Release.Name }}
|
||||
{{- end -}}
|
@@ -1,37 +0,0 @@
|
||||
# somevolumes
|
||||
|
||||
A Helm chart for somevolumes
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
# Standard Helm install
|
||||
$ helm install my-release somevolumes
|
||||
|
||||
# To use a custom namespace and force the creation of the namespace
|
||||
$ helm install my-release --namespace my-namespace --create-namespace somevolumes
|
||||
|
||||
# To use a custom values file
|
||||
$ helm install my-release -f my-values.yaml somevolumes
|
||||
```
|
||||
|
||||
See the [Helm documentation](https://helm.sh/docs/intro/using_helm/) for more information on installing and managing the chart.
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters of the somevolumes chart and their default values.
|
||||
|
||||
| Parameter | Default |
|
||||
| ----------------------------------------------- | ----------------- |
|
||||
| `site1.imagePullPolicy` | `IfNotPresent` |
|
||||
| `site1.persistence.statics.accessMode[0].value` | `ReadWriteOnce` |
|
||||
| `site1.persistence.statics.enabled` | `true` |
|
||||
| `site1.persistence.statics.size` | `1Gi` |
|
||||
| `site1.persistence.statics.storageClass` | `-` |
|
||||
| `site1.replicas` | `1` |
|
||||
| `site1.repository.image` | `docker.io/nginx` |
|
||||
| `site1.repository.tag` | `1` |
|
||||
|
||||
|
@@ -1,27 +0,0 @@
|
||||
Your release is named {{ .Release.Name }}.
|
||||
|
||||
To learn more about the release, try:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} status {{ .Release.Name }}
|
||||
$ helm -n {{ .Release.Namespace }} get all {{ .Release.Name }}
|
||||
|
||||
To delete the release, run:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} delete {{ .Release.Name }}
|
||||
|
||||
You can see this notes again by running:
|
||||
|
||||
$ helm -n {{ .Release.Namespace }} get notes {{ .Release.Name }}
|
||||
|
||||
{{- $count := 0 -}}
|
||||
{{- range $s, $v := .Values -}}
|
||||
{{- if and $v $v.ingress -}}
|
||||
{{- $count = add $count 1 -}}
|
||||
{{- if eq $count 1 }}
|
||||
|
||||
The ingress list is:
|
||||
{{ end }}
|
||||
- {{ $s }}: http://{{ $v.ingress.host }}{{ $v.ingress.path }}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
@@ -1,36 +0,0 @@
|
||||
{{- define "somevolumes.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "somevolumes.name" -}}
|
||||
{{- if .Values.nameOverride -}}
|
||||
{{- .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "somevolumes.labels" -}}
|
||||
{{ include "somevolumes.selectorLabels" .}}
|
||||
{{ if .Chart.Version -}}
|
||||
{{ printf "katenary.v3/chart-version: %s" .Chart.Version }}
|
||||
{{- end }}
|
||||
{{ if .Chart.AppVersion -}}
|
||||
{{ printf "katenary.v3/app-version: %s" .Chart.AppVersion }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "somevolumes.selectorLabels" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{ printf "katenary.v3/name: %s" $name }}
|
||||
{{ printf "katenary.v3/instance: %s" .Release.Name }}
|
||||
{{- end -}}
|
@@ -2,7 +2,8 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"os"
|
||||
@@ -136,7 +137,7 @@ func (chart *HelmChart) generateConfigMapsAndSecrets(project *types.Project) err
|
||||
originalEnv[k] = v
|
||||
}
|
||||
|
||||
if v, ok := s.Labels[LabelSecrets]; ok {
|
||||
if v, ok := s.Labels[labels.LabelSecrets]; ok {
|
||||
list, err := labelStructs.SecretsFrom(v)
|
||||
if err != nil {
|
||||
log.Fatal("error unmarshaling secrets label:", err)
|
||||
@@ -210,7 +211,8 @@ func (chart *HelmChart) generateDeployment(service types.ServiceConfig, deployme
|
||||
|
||||
// get the same-pod label if exists, add it to the list.
|
||||
// We later will copy some parts to the target deployment and remove this one.
|
||||
if samePod, ok := service.Labels[LabelSamePod]; ok && samePod != "" {
|
||||
if samePod, ok := service.Labels[labels.LabelSamePod]; ok && samePod != "" {
|
||||
log.Printf("Found same-pod label for %s", service.Name)
|
||||
podToMerge[samePod] = &service
|
||||
}
|
||||
|
||||
@@ -247,7 +249,7 @@ func (chart *HelmChart) setChartVersion(service types.ServiceConfig) {
|
||||
|
||||
// setCronJob creates a cronjob from the service labels.
|
||||
func (chart *HelmChart) setCronJob(service types.ServiceConfig, appName string) *CronJob {
|
||||
if _, ok := service.Labels[LabelCronJob]; !ok {
|
||||
if _, ok := service.Labels[labels.LabelCronJob]; !ok {
|
||||
return nil
|
||||
}
|
||||
cronjob, rbac := NewCronJob(service, chart, appName)
|
||||
@@ -281,7 +283,7 @@ func (chart *HelmChart) setCronJob(service types.ServiceConfig, appName string)
|
||||
// setDependencies sets the dependencies from the service labels.
|
||||
func (chart *HelmChart) setDependencies(service types.ServiceConfig) (bool, error) {
|
||||
// helm dependency
|
||||
if v, ok := service.Labels[LabelDependencies]; ok {
|
||||
if v, ok := service.Labels[labels.LabelDependencies]; ok {
|
||||
d, err := labelStructs.DependenciesFrom(v)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -307,10 +309,10 @@ func (chart *HelmChart) setDependencies(service types.ServiceConfig) (bool, erro
|
||||
func (chart *HelmChart) setSharedConf(service types.ServiceConfig, deployments map[string]*Deployment) {
|
||||
// if the service has the "shared-conf" label, we need to add the configmap
|
||||
// to the chart and add the env vars to the service
|
||||
if _, ok := service.Labels[LabelEnvFrom]; !ok {
|
||||
if _, ok := service.Labels[labels.LabelEnvFrom]; !ok {
|
||||
return
|
||||
}
|
||||
fromservices, err := labelStructs.EnvFromFrom(service.Labels[LabelEnvFrom])
|
||||
fromservices, err := labelStructs.EnvFromFrom(service.Labels[labels.LabelEnvFrom])
|
||||
if err != nil {
|
||||
log.Fatal("error unmarshaling env-from label:", err)
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"os"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// FileMapUsage is the usage of the filemap.
|
||||
@@ -74,7 +74,7 @@ func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *Co
|
||||
}
|
||||
|
||||
// get the secrets from the labels
|
||||
secrets, err := labelStructs.SecretsFrom(service.Labels[LabelSecrets])
|
||||
secrets, err := labelStructs.SecretsFrom(service.Labels[labels.LabelSecrets])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *Co
|
||||
drop[secret] = true
|
||||
}
|
||||
// get the label values from the labels
|
||||
varDescriptons := utils.GetValuesFromLabel(service, LabelValues)
|
||||
varDescriptons := utils.GetValuesFromLabel(service, labels.LabelValues)
|
||||
for value := range varDescriptons {
|
||||
labelValues = append(labelValues, value)
|
||||
}
|
||||
@@ -99,7 +99,7 @@ func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *Co
|
||||
if !forFile {
|
||||
// do not bind env variables to the configmap
|
||||
// remove the variables that are already defined in the environment
|
||||
if l, ok := service.Labels[LabelMapEnv]; ok {
|
||||
if l, ok := service.Labels[labels.LabelMapEnv]; ok {
|
||||
envmap, err := labelStructs.MapEnvFrom(l)
|
||||
if err != nil {
|
||||
log.Fatal("Error parsing map-env", err)
|
||||
@@ -232,9 +232,5 @@ func (c *ConfigMap) SetData(data map[string]string) {
|
||||
|
||||
// Yaml returns the yaml representation of the configmap
|
||||
func (c *ConfigMap) Yaml() ([]byte, error) {
|
||||
if o, err := yaml.Marshal(c); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return UnWrapTPL(o), nil
|
||||
}
|
||||
return ToK8SYaml(c)
|
||||
}
|
||||
|
@@ -5,7 +5,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"katenary/generator/extrafiles"
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/katenaryfile"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/parser"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
@@ -125,6 +127,9 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// TODO: use katenary.yaml file here to set the labels
|
||||
katenaryfile.OverrideWithConfig(project)
|
||||
|
||||
if !config.Force {
|
||||
// check if the chart directory exists
|
||||
// if yes, prevent the user from overwriting it and ask for confirmation
|
||||
@@ -264,7 +269,7 @@ func addDependencyDescription(values []byte, dependencies []labelStructs.Depende
|
||||
// of the service definition.
|
||||
func addDescriptions(values []byte, project types.Project) []byte {
|
||||
for _, service := range project.Services {
|
||||
if description, ok := service.Labels[LabelDescription]; ok {
|
||||
if description, ok := service.Labels[labels.LabelDescription]; ok {
|
||||
// set it as comment
|
||||
description = "\n# " + strings.ReplaceAll(description, "\n", "\n# ")
|
||||
|
||||
@@ -288,7 +293,7 @@ func addDescriptions(values []byte, project types.Project) []byte {
|
||||
|
||||
func addDocToVariable(service types.ServiceConfig, lines []string) []string {
|
||||
currentService := ""
|
||||
variables := utils.GetValuesFromLabel(service, LabelValues)
|
||||
variables := utils.GetValuesFromLabel(service, labels.LabelValues)
|
||||
for i, line := range lines {
|
||||
// if the line is a service, it is a name followed by a colon
|
||||
if regexp.MustCompile(`(?m)^` + service.Name + `:`).MatchString(line) {
|
||||
@@ -378,7 +383,7 @@ func addMainTagAppDoc(values []byte, project *types.Project) []byte {
|
||||
|
||||
for _, service := range project.Services {
|
||||
// read the label LabelMainApp
|
||||
if v, ok := service.Labels[LabelMainApp]; !ok {
|
||||
if v, ok := service.Labels[labels.LabelMainApp]; !ok {
|
||||
continue
|
||||
} else if v == "false" || v == "no" || v == "0" {
|
||||
continue
|
||||
@@ -651,7 +656,7 @@ func checkOldLabels(project *types.Project) error {
|
||||
badServices := make([]string, 0)
|
||||
for _, service := range project.Services {
|
||||
for label := range service.Labels {
|
||||
if strings.Contains(label, "katenary.") && !strings.Contains(label, katenaryLabelPrefix) {
|
||||
if strings.Contains(label, "katenary.") && !strings.Contains(label, labels.KatenaryLabelPrefix) {
|
||||
badServices = append(badServices, fmt.Sprintf("- %s: %s", service.Name, label))
|
||||
}
|
||||
}
|
||||
@@ -667,7 +672,7 @@ func checkOldLabels(project *types.Project) error {
|
||||
Services to upgrade:
|
||||
%s`,
|
||||
project.Name,
|
||||
katenaryLabelPrefix[0:len(katenaryLabelPrefix)-1],
|
||||
labels.KatenaryLabelPrefix[0:len(labels.KatenaryLabelPrefix)-1],
|
||||
strings.Join(badServices, "\n"),
|
||||
)
|
||||
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"strings"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// only used to check interface implementation
|
||||
@@ -26,7 +26,7 @@ type CronJob struct {
|
||||
|
||||
// NewCronJob creates a new CronJob from a compose service. The appName is the name of the application taken from the project name.
|
||||
func NewCronJob(service types.ServiceConfig, chart *HelmChart, appName string) (*CronJob, *RBAC) {
|
||||
labels, ok := service.Labels[LabelCronJob]
|
||||
labels, ok := service.Labels[labels.LabelCronJob]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -119,9 +119,5 @@ func (c *CronJob) Filename() string {
|
||||
//
|
||||
// Implements the Yaml interface.
|
||||
func (c *CronJob) Yaml() ([]byte, error) {
|
||||
if o, err := yaml.Marshal(c); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return UnWrapTPL(o), nil
|
||||
}
|
||||
return ToK8SYaml(c)
|
||||
}
|
||||
|
@@ -2,7 +2,8 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"os"
|
||||
@@ -15,7 +16,6 @@ import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var _ Yaml = (*Deployment)(nil)
|
||||
@@ -45,7 +45,7 @@ type Deployment struct {
|
||||
// It also creates the Values map that will be used to create the values.yaml file.
|
||||
func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment {
|
||||
isMainApp := false
|
||||
if mainLabel, ok := service.Labels[LabelMainApp]; ok {
|
||||
if mainLabel, ok := service.Labels[labels.LabelMainApp]; ok {
|
||||
main := strings.ToLower(mainLabel)
|
||||
isMainApp = main == "true" || main == "yes" || main == "1"
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment {
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
NodeSelector: map[string]string{
|
||||
labelName("node-selector"): "replace",
|
||||
labels.LabelName("node-selector"): "replace",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -155,7 +155,7 @@ func (d *Deployment) AddContainer(service types.ServiceConfig) {
|
||||
|
||||
func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *corev1.Container) {
|
||||
// get the label for healthcheck
|
||||
if v, ok := service.Labels[LabelHealthCheck]; ok {
|
||||
if v, ok := service.Labels[labels.LabelHealthCheck]; ok {
|
||||
probes, err := labelStructs.ProbeFrom(v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -190,7 +190,7 @@ func (d *Deployment) AddIngress(service types.ServiceConfig, appName string) *In
|
||||
// If the volume is a bind volume it will warn the user that it is not supported yet.
|
||||
func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
tobind := map[string]bool{}
|
||||
if v, ok := service.Labels[LabelConfigMapFiles]; ok {
|
||||
if v, ok := service.Labels[labels.LabelConfigMapFiles]; ok {
|
||||
binds, err := labelStructs.ConfigMapFileFrom(v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -201,7 +201,7 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
}
|
||||
|
||||
isSamePod := false
|
||||
if v, ok := service.Labels[LabelSamePod]; !ok {
|
||||
if v, ok := service.Labels[labels.LabelSamePod]; !ok {
|
||||
isSamePod = false
|
||||
} else {
|
||||
isSamePod = v != ""
|
||||
@@ -246,7 +246,12 @@ func (d *Deployment) DependsOn(to *Deployment, servicename string) error {
|
||||
for _, container := range to.Spec.Template.Spec.Containers {
|
||||
commands := []string{}
|
||||
if len(container.Ports) == 0 {
|
||||
utils.Warn("No ports found for service ", servicename, ". You should declare a port in the service or use "+LabelPorts+" label.")
|
||||
utils.Warn("No ports found for service ",
|
||||
servicename,
|
||||
". You should declare a port in the service or use "+
|
||||
labels.LabelPorts+
|
||||
" label.",
|
||||
)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, port := range container.Ports {
|
||||
@@ -280,13 +285,13 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) {
|
||||
secrets := []string{}
|
||||
|
||||
// secrets from label
|
||||
labelSecrets, err := labelStructs.SecretsFrom(service.Labels[LabelSecrets])
|
||||
labelSecrets, err := labelStructs.SecretsFrom(service.Labels[labels.LabelSecrets])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// values from label
|
||||
varDescriptons := utils.GetValuesFromLabel(service, LabelValues)
|
||||
varDescriptons := utils.GetValuesFromLabel(service, labels.LabelValues)
|
||||
labelValues := []string{}
|
||||
for v := range varDescriptons {
|
||||
labelValues = append(labelValues, v)
|
||||
@@ -365,12 +370,13 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) {
|
||||
|
||||
// Yaml returns the yaml representation of the deployment.
|
||||
func (d *Deployment) Yaml() ([]byte, error) {
|
||||
var y []byte
|
||||
var err error
|
||||
serviceName := d.service.Name
|
||||
y, err := yaml.Marshal(d)
|
||||
if err != nil {
|
||||
|
||||
if y, err = ToK8SYaml(d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y = UnWrapTPL(y)
|
||||
|
||||
// for each volume mount, add a condition "if values has persistence"
|
||||
changing := false
|
||||
@@ -506,7 +512,7 @@ func (d *Deployment) Yaml() ([]byte, error) {
|
||||
|
||||
// find the katenary.v3/node-selector line, and remove it
|
||||
for i, line := range content {
|
||||
if strings.Contains(line, labelName("node-selector")) {
|
||||
if strings.Contains(line, labels.LabelName("node-selector")) {
|
||||
content = append(content[:i], content[i+1:]...)
|
||||
continue
|
||||
}
|
||||
@@ -582,7 +588,7 @@ func (d *Deployment) bindVolumes(volume types.ServiceVolumeConfig, isSamePod boo
|
||||
utils.Warn(
|
||||
"Bind volumes are not supported yet, " +
|
||||
"excepting for those declared as " +
|
||||
LabelConfigMapFiles +
|
||||
labels.LabelConfigMapFiles +
|
||||
", skipping volume " + volume.Source +
|
||||
" from service " + service.Name,
|
||||
)
|
||||
@@ -612,7 +618,7 @@ func (d *Deployment) bindVolumes(volume types.ServiceVolumeConfig, isSamePod boo
|
||||
})
|
||||
// Add volume to values.yaml only if it the service is not in the same pod that another service.
|
||||
// If it is in the same pod, the volume will be added to the other service later
|
||||
if _, ok := service.Labels[LabelSamePod]; !ok {
|
||||
if _, ok := service.Labels[labels.LabelSamePod]; !ok {
|
||||
d.chart.Values[service.Name].(*Value).AddPersistence(volume.Source)
|
||||
}
|
||||
// Add volume to deployment
|
||||
|
@@ -2,6 +2,7 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -159,7 +160,7 @@ services:
|
||||
version: 18.x.X
|
||||
|
||||
`
|
||||
composeFile = fmt.Sprintf(composeFile, Prefix())
|
||||
composeFile = fmt.Sprintf(composeFile, labels.Prefix())
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
@@ -249,7 +250,7 @@ services:
|
||||
path: /ready
|
||||
port: 80
|
||||
`
|
||||
composeFile = fmt.Sprintf(composeFile, Prefix())
|
||||
composeFile = fmt.Sprintf(composeFile, labels.Prefix())
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
@@ -295,7 +296,7 @@ services:
|
||||
- FOO
|
||||
`
|
||||
|
||||
composeFile = fmt.Sprintf(composeFile, Prefix())
|
||||
composeFile = fmt.Sprintf(composeFile, labels.Prefix())
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package generator
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"regexp"
|
||||
@@ -39,7 +40,7 @@ func Generate(project *types.Project) (*HelmChart, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Annotations[labelName("compose-hash")] = hash
|
||||
Annotations[labels.LabelName("compose-hash")] = hash
|
||||
chart.composeHash = &hash
|
||||
|
||||
// find the "main-app" label, and set chart.AppVersion to the tag if exists
|
||||
@@ -81,14 +82,14 @@ func Generate(project *types.Project) (*HelmChart, error) {
|
||||
// drop all "same-pod" deployments because the containers and volumes are already
|
||||
// in the target deployment
|
||||
for _, service := range podToMerge {
|
||||
if samepod, ok := service.Labels[LabelSamePod]; ok && samepod != "" {
|
||||
if samepod, ok := service.Labels[labels.LabelSamePod]; ok && samepod != "" {
|
||||
// move this deployment volumes to the target deployment
|
||||
if target, ok := deployments[samepod]; ok {
|
||||
target.AddContainer(*service)
|
||||
target.BindFrom(*service, deployments[service.Name])
|
||||
delete(deployments, service.Name)
|
||||
} else {
|
||||
log.Printf("service %[1]s is declared as %[2]s, but %[2]s is not defined", service.Name, LabelSamePod)
|
||||
log.Printf("service %[1]s is declared as %[2]s, but %[2]s is not defined", service.Name, labels.LabelSamePod)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +164,7 @@ func Generate(project *types.Project) (*HelmChart, error) {
|
||||
|
||||
// serviceIsMain returns true if the service is the main app.
|
||||
func serviceIsMain(service types.ServiceConfig) bool {
|
||||
if main, ok := service.Labels[LabelMainApp]; ok {
|
||||
if main, ok := service.Labels[labels.LabelMainApp]; ok {
|
||||
return main == "true" || main == "yes" || main == "1"
|
||||
}
|
||||
return false
|
||||
@@ -276,7 +277,7 @@ func buildVolumes(service types.ServiceConfig, chart *HelmChart, deployments map
|
||||
|
||||
// if the service is integrated in another deployment, we need to add the volume
|
||||
// to the target deployment
|
||||
if override, ok := service.Labels[LabelSamePod]; ok {
|
||||
if override, ok := service.Labels[labels.LabelSamePod]; ok {
|
||||
pvc.nameOverride = override
|
||||
pvc.Spec.StorageClassName = utils.StrPtr(`{{ .Values.` + override + `.persistence.` + v.Source + `.storageClass }}`)
|
||||
chart.Values[override].(*Value).AddPersistence(v.Source)
|
||||
@@ -308,7 +309,7 @@ func samePodVolume(service types.ServiceConfig, v types.ServiceVolumeConfig, dep
|
||||
}
|
||||
|
||||
targetDeployment := ""
|
||||
if targetName, ok := service.Labels[LabelSamePod]; !ok {
|
||||
if targetName, ok := service.Labels[labels.LabelSamePod]; !ok {
|
||||
return false
|
||||
} else {
|
||||
targetDeployment = targetName
|
||||
|
@@ -1,6 +1,9 @@
|
||||
package generator
|
||||
|
||||
import "regexp"
|
||||
import (
|
||||
"katenary/generator/labels"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
// find all labels starting by __replace_ and ending with ":"
|
||||
@@ -11,6 +14,6 @@ var (
|
||||
|
||||
// Standard annotationss
|
||||
Annotations = map[string]string{
|
||||
labelName("version"): Version,
|
||||
labels.LabelName("version"): Version,
|
||||
}
|
||||
)
|
||||
|
@@ -2,6 +2,7 @@ package generator
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"katenary/generator/labels"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -13,7 +14,7 @@ var helmHelper string
|
||||
// Helper returns the _helpers.tpl file for a chart.
|
||||
func Helper(name string) string {
|
||||
helmHelper := strings.ReplaceAll(helmHelper, "__APP__", name)
|
||||
helmHelper = strings.ReplaceAll(helmHelper, "__PREFIX__", katenaryLabelPrefix)
|
||||
helmHelper = strings.ReplaceAll(helmHelper, "__PREFIX__", labels.KatenaryLabelPrefix)
|
||||
helmHelper = strings.ReplaceAll(helmHelper, "__VERSION__", "0.1.0")
|
||||
return helmHelper
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"strings"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
networkv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var _ Yaml = (*Ingress)(nil)
|
||||
@@ -28,7 +28,7 @@ func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress {
|
||||
}
|
||||
var label string
|
||||
var ok bool
|
||||
if label, ok = service.Labels[LabelIngress]; !ok {
|
||||
if label, ok = service.Labels[labels.LabelIngress]; !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -124,8 +124,13 @@ func (ingress *Ingress) Filename() string {
|
||||
}
|
||||
|
||||
func (ingress *Ingress) Yaml() ([]byte, error) {
|
||||
var ret []byte
|
||||
var err error
|
||||
if ret, err = ToK8SYaml(ingress); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serviceName := ingress.service.Name
|
||||
ret, err := yaml.Marshal(ingress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -22,7 +23,7 @@ services:
|
||||
hostname: my.test.tld
|
||||
port: 80
|
||||
`
|
||||
composeFile = fmt.Sprintf(composeFile, katenaryLabelPrefix)
|
||||
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
|
10
generator/katenaryfile/doc.go
Normal file
10
generator/katenaryfile/doc.go
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
Package katenaryfile is a package for reading and writing katenary files.
|
||||
|
||||
A katenary file, named "katenary.yml" or "katenary.yaml", is a file where you can define the
|
||||
configuration of the conversion avoiding the use of labels in the compose file.
|
||||
|
||||
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.
|
||||
*/
|
||||
package katenaryfile
|
142
generator/katenaryfile/main.go
Normal file
142
generator/katenaryfile/main.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package katenaryfile
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/invopop/jsonschema"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var allowedKatenaryYamlFileNames = []string{"katenary.yaml", "katenary.yml"}
|
||||
|
||||
// StringOrMap is a struct that can be either a string or a map of strings.
|
||||
// It's a helper struct to unmarshal the katenary.yaml file and produce the schema
|
||||
type StringOrMap any
|
||||
|
||||
// Service is a struct that contains the service configuration for katenary
|
||||
type Service struct {
|
||||
MainApp *bool `json:"main-app,omitempty" jsonschema:"title=Is this service the main application"`
|
||||
Values []StringOrMap `json:"values,omitempty" jsonschema:"description=Environment variables to be set in values.yaml with or without a description"`
|
||||
Secrets *labelStructs.Secrets `json:"secrets,omitempty" jsonschema:"title=Secrets,description=Environment variables to be set as secrets"`
|
||||
Ports *labelStructs.Ports `json:"ports,omitempty" jsonschema:"title=Ports,description=Ports to be exposed in services"`
|
||||
Ingress *labelStructs.Ingress `json:"ingress,omitempty" jsonschema:"title=Ingress,description=Ingress configuration"`
|
||||
HealthCheck *labelStructs.HealthCheck `json:"health-check,omitempty" jsonschema:"title=Health Check,description=Health check configuration that respects the kubernetes api"`
|
||||
SamePod *string `json:"same-pod,omitempty" jsonschema:"title=Same Pod,description=Service that should be in the same pod"`
|
||||
Description *string `json:"description,omitempty" jsonschema:"title=Description,description=Description of the service that will be injected in the values.yaml file"`
|
||||
Ignore *bool `json:"ignore,omitempty" jsonschema:"title=Ignore,description=Ignore the service in the conversion"`
|
||||
Dependencies []labelStructs.Dependency `json:"dependencies,omitempty" jsonschema:"title=Dependencies,description=Services that should be injected in the Chart.yaml file"`
|
||||
ConfigMapFile *labelStructs.ConfigMapFile `json:"configmap-files,omitempty" jsonschema:"title=ConfigMap Files,description=Files that should be injected as ConfigMap"`
|
||||
MapEnv *labelStructs.MapEnv `json:"map-env,omitempty" jsonschema:"title=Map Env,description=Map environment variables to another value"`
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
func OverrideWithConfig(project *types.Project) {
|
||||
var yamlFile string
|
||||
var err error
|
||||
for _, yamlFile = range allowedKatenaryYamlFileNames {
|
||||
_, err = os.Stat(yamlFile)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
// no katenary file found
|
||||
return
|
||||
}
|
||||
fmt.Println(utils.IconInfo, "Using katenary file", yamlFile)
|
||||
|
||||
services := make(map[string]Service)
|
||||
fp, err := os.Open(yamlFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := yaml.NewDecoder(fp).Decode(&services); err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
for i, p := range project.Services {
|
||||
name := p.Name
|
||||
if project.Services[i].Labels == nil {
|
||||
project.Services[i].Labels = make(map[string]string)
|
||||
}
|
||||
|
||||
if s, ok := services[name]; ok {
|
||||
getLabelContent(s.MainApp, &project.Services[i], labels.LabelMainApp)
|
||||
getLabelContent(s.Values, &project.Services[i], labels.LabelValues)
|
||||
getLabelContent(s.Secrets, &project.Services[i], labels.LabelSecrets)
|
||||
getLabelContent(s.Ports, &project.Services[i], labels.LabelPorts)
|
||||
getLabelContent(s.Ingress, &project.Services[i], labels.LabelIngress)
|
||||
getLabelContent(s.HealthCheck, &project.Services[i], labels.LabelHealthCheck)
|
||||
getLabelContent(s.SamePod, &project.Services[i], labels.LabelSamePod)
|
||||
getLabelContent(s.Description, &project.Services[i], labels.LabelDescription)
|
||||
getLabelContent(s.Ignore, &project.Services[i], labels.LabelIgnore)
|
||||
getLabelContent(s.Dependencies, &project.Services[i], labels.LabelDependencies)
|
||||
getLabelContent(s.ConfigMapFile, &project.Services[i], labels.LabelConfigMapFiles)
|
||||
getLabelContent(s.MapEnv, &project.Services[i], labels.LabelMapEnv)
|
||||
getLabelContent(s.CronJob, &project.Services[i], labels.LabelCronJob)
|
||||
getLabelContent(s.EnvFrom, &project.Services[i], labels.LabelEnvFrom)
|
||||
}
|
||||
}
|
||||
fmt.Println(utils.IconInfo, "Katenary file loaded successfully, the services are now configured.")
|
||||
}
|
||||
|
||||
func getLabelContent(o any, service *types.ServiceConfig, labelName string) error {
|
||||
if reflect.ValueOf(o).IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := yaml.Marshal(o)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
val := strings.TrimSpace(string(c))
|
||||
|
||||
service.Labels[labelName] = val
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateSchema generates the schema for the katenary.yaml file.
|
||||
func GenerateSchema() string {
|
||||
s := jsonschema.Reflect(map[string]Service{})
|
||||
|
||||
// redefine the IntOrString type from k8s
|
||||
s.Definitions["IntOrString"] = &jsonschema.Schema{
|
||||
OneOf: []*jsonschema.Schema{
|
||||
{Type: "integer"},
|
||||
{Type: "string"},
|
||||
},
|
||||
}
|
||||
|
||||
// same for the StringOrMap type, that can be either a string or a map of string:string
|
||||
s.Definitions["StringOrMap"] = &jsonschema.Schema{
|
||||
OneOf: []*jsonschema.Schema{
|
||||
{Type: "string"},
|
||||
{Type: "object", AdditionalProperties: &jsonschema.Schema{Type: "string"}},
|
||||
},
|
||||
}
|
||||
|
||||
c, _ := s.MarshalJSON()
|
||||
// indent the json
|
||||
var out bytes.Buffer
|
||||
err := json.Indent(&out, c, "", " ")
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return string(out.Bytes())
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
package labelStructs
|
||||
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
type TLS struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Ingress struct {
|
||||
Port *int32 `yaml:"port,omitempty"`
|
||||
Annotations map[string]string `yaml:"annotations,omitempty"`
|
||||
Hostname string `yaml:"hostname"`
|
||||
Path string `yaml:"path"`
|
||||
Class string `yaml:"class"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
TLS TLS `yaml:"tls"`
|
||||
}
|
||||
|
||||
// IngressFrom creates a new Ingress from a compose service.
|
||||
func IngressFrom(data string) (*Ingress, error) {
|
||||
mapping := Ingress{
|
||||
Hostname: "",
|
||||
Path: "/",
|
||||
Enabled: false,
|
||||
Class: "-",
|
||||
Port: nil,
|
||||
TLS: TLS{Enabled: true},
|
||||
}
|
||||
if err := yaml.Unmarshal([]byte(data), &mapping); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mapping, nil
|
||||
}
|
@@ -2,9 +2,10 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
)
|
||||
|
||||
var componentLabel = labelName("component")
|
||||
var componentLabel = labels.LabelName("component")
|
||||
|
||||
// GetLabels returns the labels for a service. It uses the appName to replace the __replace__ in the labels.
|
||||
// This is used to generate the labels in the templates.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package generator
|
||||
package labels
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -14,24 +14,24 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
const katenaryLabelPrefix = "katenary.v3"
|
||||
const KatenaryLabelPrefix = "katenary.v3"
|
||||
|
||||
// Known labels.
|
||||
const (
|
||||
LabelMainApp Label = katenaryLabelPrefix + "/main-app"
|
||||
LabelValues Label = katenaryLabelPrefix + "/values"
|
||||
LabelSecrets Label = katenaryLabelPrefix + "/secrets"
|
||||
LabelPorts Label = katenaryLabelPrefix + "/ports"
|
||||
LabelIngress Label = katenaryLabelPrefix + "/ingress"
|
||||
LabelMapEnv Label = katenaryLabelPrefix + "/map-env"
|
||||
LabelHealthCheck Label = katenaryLabelPrefix + "/health-check"
|
||||
LabelSamePod Label = katenaryLabelPrefix + "/same-pod"
|
||||
LabelDescription Label = katenaryLabelPrefix + "/description"
|
||||
LabelIgnore Label = katenaryLabelPrefix + "/ignore"
|
||||
LabelDependencies Label = katenaryLabelPrefix + "/dependencies"
|
||||
LabelConfigMapFiles Label = katenaryLabelPrefix + "/configmap-files"
|
||||
LabelCronJob Label = katenaryLabelPrefix + "/cronjob"
|
||||
LabelEnvFrom Label = katenaryLabelPrefix + "/env-from"
|
||||
LabelMainApp Label = KatenaryLabelPrefix + "/main-app"
|
||||
LabelValues Label = KatenaryLabelPrefix + "/values"
|
||||
LabelSecrets Label = KatenaryLabelPrefix + "/secrets"
|
||||
LabelPorts Label = KatenaryLabelPrefix + "/ports"
|
||||
LabelIngress Label = KatenaryLabelPrefix + "/ingress"
|
||||
LabelMapEnv Label = KatenaryLabelPrefix + "/map-env"
|
||||
LabelHealthCheck Label = KatenaryLabelPrefix + "/health-check"
|
||||
LabelSamePod Label = KatenaryLabelPrefix + "/same-pod"
|
||||
LabelDescription Label = KatenaryLabelPrefix + "/description"
|
||||
LabelIgnore Label = KatenaryLabelPrefix + "/ignore"
|
||||
LabelDependencies Label = KatenaryLabelPrefix + "/dependencies"
|
||||
LabelConfigMapFiles Label = KatenaryLabelPrefix + "/configmap-files"
|
||||
LabelCronJob Label = KatenaryLabelPrefix + "/cronjob"
|
||||
LabelEnvFrom Label = KatenaryLabelPrefix + "/env-from"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -47,8 +47,8 @@ var (
|
||||
// Label is a katenary label to find in compose files.
|
||||
type Label = string
|
||||
|
||||
func labelName(name string) Label {
|
||||
return Label(katenaryLabelPrefix + "/" + name)
|
||||
func LabelName(name string) Label {
|
||||
return Label(KatenaryLabelPrefix + "/" + name)
|
||||
}
|
||||
|
||||
// Help is the documentation of a label.
|
||||
@@ -114,7 +114,7 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
||||
template.Must(template.New("shorthelp").Parse(help.Long)).Execute(&buf, struct {
|
||||
KatenaryPrefix string
|
||||
}{
|
||||
KatenaryPrefix: katenaryLabelPrefix,
|
||||
KatenaryPrefix: KatenaryLabelPrefix,
|
||||
})
|
||||
help.Long = buf.String()
|
||||
buf.Reset()
|
||||
@@ -122,7 +122,7 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
||||
template.Must(template.New("example").Parse(help.Example)).Execute(&buf, struct {
|
||||
KatenaryPrefix string
|
||||
}{
|
||||
KatenaryPrefix: katenaryLabelPrefix,
|
||||
KatenaryPrefix: KatenaryLabelPrefix,
|
||||
})
|
||||
help.Example = buf.String()
|
||||
buf.Reset()
|
||||
@@ -134,7 +134,7 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
||||
}{
|
||||
Name: labelname,
|
||||
Help: help,
|
||||
KatenaryPrefix: katenaryLabelPrefix,
|
||||
KatenaryPrefix: KatenaryLabelPrefix,
|
||||
})
|
||||
|
||||
return buf.String()
|
||||
@@ -152,7 +152,7 @@ func generateMarkdownHelp(names []string) string {
|
||||
}
|
||||
for _, name := range names {
|
||||
help := labelFullHelp[name]
|
||||
maxNameLength = max(maxNameLength, len(name)+2+len(katenaryLabelPrefix))
|
||||
maxNameLength = max(maxNameLength, len(name)+2+len(KatenaryLabelPrefix))
|
||||
maxDescriptionLength = max(maxDescriptionLength, len(help.Short))
|
||||
maxTypeLength = max(maxTypeLength, len(help.Type))
|
||||
}
|
||||
@@ -163,7 +163,7 @@ func generateMarkdownHelp(names []string) string {
|
||||
for _, name := range names {
|
||||
help := labelFullHelp[name]
|
||||
fmt.Fprintf(&builder, "| %-*s | %-*s | %-*s |\n",
|
||||
maxNameLength, "`"+labelName(name)+"`", // enclose in backticks
|
||||
maxNameLength, "`"+LabelName(name)+"`", // enclose in backticks
|
||||
maxDescriptionLength, help.Short,
|
||||
maxTypeLength, help.Type,
|
||||
)
|
||||
@@ -176,7 +176,7 @@ func generatePlainHelp(names []string) string {
|
||||
var builder strings.Builder
|
||||
for _, name := range names {
|
||||
help := labelFullHelp[name]
|
||||
fmt.Fprintf(&builder, "%s:\t%s\t%s\n", labelName(name), help.Type, help.Short)
|
||||
fmt.Fprintf(&builder, "%s:\t%s\t%s\n", LabelName(name), help.Type, help.Short)
|
||||
}
|
||||
|
||||
// use tabwriter to align the help text
|
||||
@@ -231,5 +231,5 @@ Example:
|
||||
}
|
||||
|
||||
func Prefix() string {
|
||||
return katenaryLabelPrefix
|
||||
return KatenaryLabelPrefix
|
||||
}
|
@@ -25,10 +25,8 @@
|
||||
short: "Mark the service as the main app."
|
||||
long: |-
|
||||
This makes the service to be the main application. Its image tag is
|
||||
considered to be the
|
||||
|
||||
Chart appVersion and to be the defaultvalue in Pod container
|
||||
image attribute.
|
||||
considered to be the Chart appVersion and to be the defaultvalue in Pod
|
||||
container image attribute.
|
||||
|
||||
!!! Warning
|
||||
This label cannot be repeated in others services. If this label is
|
@@ -1,4 +1,4 @@
|
||||
package generator
|
||||
package labels
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
@@ -48,7 +48,7 @@ func TestLabelName(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := labelName(tt.args.name); !reflect.DeepEqual(got, tt.want) {
|
||||
if got := LabelName(tt.args.name); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("labelName() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
@@ -3,10 +3,10 @@ package labelStructs
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
type CronJob struct {
|
||||
Image string `yaml:"image,omitempty"`
|
||||
Command string `yaml:"command"`
|
||||
Schedule string `yaml:"schedule"`
|
||||
Rbac bool `yaml:"rbac"`
|
||||
Image string `yaml:"image,omitempty" json:"image,omitempty"`
|
||||
Command string `yaml:"command" json:"command,omitempty"`
|
||||
Schedule string `yaml:"schedule" json:"schedule,omitempty"`
|
||||
Rbac bool `yaml:"rbac" json:"rbac,omitempty"`
|
||||
}
|
||||
|
||||
func CronJobFrom(data string) (*CronJob, error) {
|
@@ -4,11 +4,11 @@ import "gopkg.in/yaml.v3"
|
||||
|
||||
// Dependency is a dependency of a chart to other charts.
|
||||
type Dependency struct {
|
||||
Values map[string]any `yaml:"-"`
|
||||
Name string `yaml:"name"`
|
||||
Version string `yaml:"version"`
|
||||
Repository string `yaml:"repository"`
|
||||
Alias string `yaml:"alias,omitempty"`
|
||||
Values map[string]any `yaml:"-" json:"values,omitempty"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Version string `yaml:"version" json:"version"`
|
||||
Repository string `yaml:"repository" json:"repository"`
|
||||
Alias string `yaml:"alias,omitempty" json:"alias,omitempty"`
|
||||
}
|
||||
|
||||
// DependenciesFrom returns a slice of dependencies from the given string.
|
33
generator/labels/labelStructs/ingress.go
Normal file
33
generator/labels/labelStructs/ingress.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package labelStructs
|
||||
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
type TLS struct {
|
||||
Enabled bool `yaml:"enabled" json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
type Ingress struct {
|
||||
Port *int32 `yaml:"port,omitempty" jsonschema:"nullable" 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:-"`
|
||||
Enabled bool `yaml:"enabled" json:"enabled,omitempty"`
|
||||
TLS *TLS `yaml:"tls,omitempty" json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// IngressFrom creates a new Ingress from a compose service.
|
||||
func IngressFrom(data string) (*Ingress, error) {
|
||||
mapping := Ingress{
|
||||
Hostname: "",
|
||||
Path: "/",
|
||||
Enabled: false,
|
||||
Class: "-",
|
||||
Port: nil,
|
||||
TLS: &TLS{Enabled: true},
|
||||
}
|
||||
if err := yaml.Unmarshal([]byte(data), &mapping); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mapping, nil
|
||||
}
|
@@ -8,13 +8,13 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type Probe struct {
|
||||
LivenessProbe *corev1.Probe `yaml:"livenessProbe,omitempty"`
|
||||
ReadinessProbe *corev1.Probe `yaml:"readinessProbe,omitempty"`
|
||||
type HealthCheck struct {
|
||||
LivenessProbe *corev1.Probe `yaml:"livenessProbe,omitempty" json:"livenessProbe,omitempty"`
|
||||
ReadinessProbe *corev1.Probe `yaml:"readinessProbe,omitempty" json:"readinessProbe,omitempty"`
|
||||
}
|
||||
|
||||
func ProbeFrom(data string) (*Probe, error) {
|
||||
mapping := Probe{}
|
||||
func ProbeFrom(data string) (*HealthCheck, error) {
|
||||
mapping := HealthCheck{}
|
||||
tmp := map[string]any{}
|
||||
err := yaml.Unmarshal([]byte(data), &tmp)
|
||||
if err != nil {
|
@@ -139,5 +139,5 @@ func (r *ServiceAccount) Filename() string {
|
||||
}
|
||||
|
||||
func (r *ServiceAccount) Yaml() ([]byte, error) {
|
||||
return yaml.Marshal(r)
|
||||
return ToK8SYaml(r)
|
||||
}
|
||||
|
@@ -2,14 +2,13 @@ package generator
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"katenary/utils"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -45,19 +44,11 @@ func NewSecret(service types.ServiceConfig, appName string) *Secret {
|
||||
|
||||
// check if the value should be in values.yaml
|
||||
valueList := []string{}
|
||||
varDescriptons := utils.GetValuesFromLabel(service, LabelValues)
|
||||
varDescriptons := utils.GetValuesFromLabel(service, labels.LabelValues)
|
||||
for value := range varDescriptons {
|
||||
valueList = append(valueList, value)
|
||||
}
|
||||
|
||||
// wrap values with quotes
|
||||
for _, value := range service.Environment {
|
||||
if value == nil {
|
||||
continue
|
||||
}
|
||||
*value = fmt.Sprintf(`"%s"`, *value)
|
||||
}
|
||||
|
||||
for _, value := range valueList {
|
||||
if val, ok := service.Environment[value]; ok {
|
||||
value = strings.TrimPrefix(value, `"`)
|
||||
@@ -80,7 +71,15 @@ func (s *Secret) AddData(key, value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
s.Data[key] = []byte(`{{ tpl ` + value + ` $ | b64enc }}`)
|
||||
valuesLabels := utils.GetValuesFromLabel(s.service, labels.LabelValues)
|
||||
if _, ok := valuesLabels[key]; ok {
|
||||
// the value should be in values.yaml
|
||||
s.Data[key] = []byte(`{{ tpl .Values.` + s.service.Name + `.environment.` + key + ` $ | b64enc }}`)
|
||||
} else {
|
||||
encoded := base64.StdEncoding.EncodeToString([]byte(value))
|
||||
s.Data[key] = []byte(encoded)
|
||||
}
|
||||
// s.Data[key] = []byte(`{{ tpl ` + value + ` $ | b64enc }}`)
|
||||
}
|
||||
|
||||
// Filename returns the filename of the secret.
|
||||
@@ -97,11 +96,11 @@ func (s *Secret) SetData(data map[string]string) {
|
||||
|
||||
// Yaml returns the yaml representation of the secret.
|
||||
func (s *Secret) Yaml() ([]byte, error) {
|
||||
y, err := yaml.Marshal(s)
|
||||
if err != nil {
|
||||
var y []byte
|
||||
var err error
|
||||
if y, err = ToK8SYaml(s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y = UnWrapTPL(y)
|
||||
|
||||
// replace the b64 value by the real value
|
||||
for _, value := range s.Data {
|
||||
|
@@ -2,6 +2,7 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -21,7 +22,7 @@ services:
|
||||
%s/secrets: |-
|
||||
- BAR
|
||||
`
|
||||
composeFile = fmt.Sprintf(composeFile, katenaryLabelPrefix)
|
||||
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
|
@@ -9,7 +9,6 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var _ Yaml = (*Service)(nil)
|
||||
@@ -80,11 +79,11 @@ func (s *Service) Filename() string {
|
||||
|
||||
// Yaml returns the yaml representation of the service.
|
||||
func (s *Service) Yaml() ([]byte, error) {
|
||||
y, err := yaml.Marshal(s)
|
||||
if err != nil {
|
||||
var y []byte
|
||||
var err error
|
||||
if y, err = ToK8SYaml(s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y = UnWrapTPL(y)
|
||||
|
||||
lines := []string{}
|
||||
for _, line := range strings.Split(string(y), "\n") {
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/generator/labels"
|
||||
"katenary/generator/labels/labelStructs"
|
||||
"katenary/utils"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var regexpLineWrap = regexp.MustCompile(`\n\s+}}`)
|
||||
@@ -45,7 +47,7 @@ func fixPorts(service *types.ServiceConfig) error {
|
||||
// check the "ports" label from container and add it to the service
|
||||
portsLabel := ""
|
||||
ok := false
|
||||
if portsLabel, ok = service.Labels[LabelPorts]; !ok {
|
||||
if portsLabel, ok = service.Labels[labels.LabelPorts]; !ok {
|
||||
return nil
|
||||
}
|
||||
ports, err := labelStructs.PortsFrom(portsLabel)
|
||||
@@ -74,7 +76,7 @@ func fixPorts(service *types.ServiceConfig) error {
|
||||
|
||||
// isIgnored returns true if the service is ignored.
|
||||
func isIgnored(service types.ServiceConfig) bool {
|
||||
if v, ok := service.Labels[LabelIgnore]; ok {
|
||||
if v, ok := service.Labels[labels.LabelIgnore]; ok {
|
||||
return v == "true" || v == "yes" || v == "1"
|
||||
}
|
||||
return false
|
||||
@@ -84,3 +86,11 @@ func isIgnored(service types.ServiceConfig) bool {
|
||||
func UnWrapTPL(in []byte) []byte {
|
||||
return regexpLineWrap.ReplaceAll(in, []byte(" }}"))
|
||||
}
|
||||
|
||||
func ToK8SYaml(obj interface{}) ([]byte, error) {
|
||||
if o, err := yaml.Marshal(obj); err != nil {
|
||||
return nil, nil
|
||||
} else {
|
||||
return UnWrapTPL(o), nil
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
const persistenceKey = "persistence"
|
||||
@@ -66,17 +65,17 @@ func (v *VolumeClaim) Filename() string {
|
||||
|
||||
// Yaml marshals a VolumeClaim into yaml.
|
||||
func (v *VolumeClaim) Yaml() ([]byte, error) {
|
||||
var out []byte
|
||||
var err error
|
||||
if out, err = ToK8SYaml(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serviceName := v.service.Name
|
||||
if v.nameOverride != "" {
|
||||
serviceName = v.nameOverride
|
||||
}
|
||||
volumeName := v.volumeName
|
||||
out, err := yaml.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = UnWrapTPL(out)
|
||||
|
||||
// replace 1Gi to {{ .Values.serviceName.volume.size }}
|
||||
out = []byte(
|
||||
|
@@ -2,6 +2,7 @@ package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"katenary/generator/labels"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -52,7 +53,7 @@ services:
|
||||
%s/configmap-files: |-
|
||||
- ./static
|
||||
`
|
||||
composeFile = fmt.Sprintf(composeFile, katenaryLabelPrefix)
|
||||
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
@@ -112,7 +113,7 @@ services:
|
||||
%s/configmap-files: |-
|
||||
- ./static/index.html
|
||||
`
|
||||
composeFile = fmt.Sprintf(composeFile, katenaryLabelPrefix)
|
||||
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
@@ -169,7 +170,7 @@ volumes:
|
||||
data:
|
||||
`
|
||||
|
||||
composeFile = fmt.Sprintf(composeFile, katenaryLabelPrefix)
|
||||
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
|
5
go.mod
5
go.mod
@@ -6,6 +6,7 @@ toolchain go1.23.2
|
||||
|
||||
require (
|
||||
github.com/compose-spec/compose-go v1.20.2
|
||||
github.com/invopop/jsonschema v0.12.0
|
||||
github.com/mitchellh/go-wordwrap v1.0.1
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/thediveo/netdb v1.1.2
|
||||
@@ -17,6 +18,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
@@ -27,6 +30,7 @@ require (
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
@@ -35,6 +39,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
|
11
go.sum
11
go.sum
@@ -1,3 +1,7 @@
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/compose-spec/compose-go v1.20.2 h1:u/yfZHn4EaHGdidrZycWpxXgFffjYULlTbRfJ51ykjQ=
|
||||
github.com/compose-spec/compose-go v1.20.2/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
@@ -32,6 +36,9 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
|
||||
github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
@@ -40,6 +47,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
@@ -78,6 +87,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/thediveo/netdb v1.1.2 h1:XdLx/YJPutxrSkPYtmCAIY5sgAvxtkS1Tz+Z0UX2I+U=
|
||||
github.com/thediveo/netdb v1.1.2/go.mod h1:KJczM//7VIIiovQO1qDooHvM8+0pt6RdRt3rVDZxEGM=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
|
Reference in New Issue
Block a user