Code cleaning
Using gofumpt. Add documentation. Some fixes on type checking and const icon type declaration.
This commit is contained in:
@@ -2,11 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/generator"
|
|
||||||
"katenary/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/generator"
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/cli"
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@@ -151,7 +152,6 @@ func generateConvertCommand() *cobra.Command {
|
|||||||
convertCmd.Flags().StringVarP(&givenAppVersion, "app-version", "a", "", "Specify the app version (in Chart.yaml)")
|
convertCmd.Flags().StringVarP(&givenAppVersion, "app-version", "a", "", "Specify the app version (in Chart.yaml)")
|
||||||
convertCmd.Flags().StringVarP(&chartVersion, "chart-version", "v", chartVersion, "Specify the chart version (in Chart.yaml)")
|
convertCmd.Flags().StringVarP(&chartVersion, "chart-version", "v", chartVersion, "Specify the chart version (in Chart.yaml)")
|
||||||
return convertCmd
|
return convertCmd
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateVersionCommand() *cobra.Command {
|
func generateVersionCommand() *cobra.Command {
|
||||||
@@ -165,7 +165,6 @@ func generateVersionCommand() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateLabelHelpCommand() *cobra.Command {
|
func generateLabelHelpCommand() *cobra.Command {
|
||||||
|
|
||||||
markdown := false
|
markdown := false
|
||||||
all := false
|
all := false
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -4,9 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/generator/extrafiles"
|
|
||||||
"katenary/parser"
|
|
||||||
"katenary/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -15,6 +12,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"katenary/generator/extrafiles"
|
||||||
|
"katenary/parser"
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
goyaml "gopkg.in/yaml.v3"
|
goyaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -34,7 +35,6 @@ const headerHelp = `# This file is autogenerated by katenary
|
|||||||
// Convert a compose (docker, podman...) project to a helm chart.
|
// Convert a compose (docker, podman...) project to a helm chart.
|
||||||
// It calls Generate() to generate the chart and then write it to the disk.
|
// It calls Generate() to generate the chart and then write it to the disk.
|
||||||
func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
templateDir = filepath.Join(config.OutputDir, "templates")
|
templateDir = filepath.Join(config.OutputDir, "templates")
|
||||||
helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl")
|
helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl")
|
||||||
@@ -103,7 +103,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
os.RemoveAll(config.OutputDir)
|
os.RemoveAll(config.OutputDir)
|
||||||
|
|
||||||
// create the chart directory
|
// create the chart directory
|
||||||
if err := os.MkdirAll(templateDir, 0755); err != nil {
|
if err := os.MkdirAll(templateDir, 0o755); err != nil {
|
||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
servicename := template.Servicename
|
servicename := template.Servicename
|
||||||
if err := os.MkdirAll(filepath.Join(templateDir, servicename), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Join(templateDir, servicename), 0o755); err != nil {
|
||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
// if the name is a path, create the directory
|
// if the name is a path, create the directory
|
||||||
if strings.Contains(name, string(filepath.Separator)) {
|
if strings.Contains(name, string(filepath.Separator)) {
|
||||||
name = filepath.Join(templateDir, name)
|
name = filepath.Join(templateDir, name)
|
||||||
err := os.MkdirAll(filepath.Dir(name), 0755)
|
err := os.MkdirAll(filepath.Dir(name), 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -163,7 +163,6 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculate the sha1 hash of the services
|
// calculate the sha1 hash of the services
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
encoder := goyaml.NewEncoder(buf)
|
encoder := goyaml.NewEncoder(buf)
|
||||||
encoder.SetIndent(2)
|
encoder.SetIndent(2)
|
||||||
@@ -437,7 +436,6 @@ func addChartDoc(values []byte, project *types.Project) []byte {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []byte(chartDoc + strings.Join(lines, "\n"))
|
return []byte(chartDoc + strings.Join(lines, "\n"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const imagePullPolicyHelp = `# imagePullPolicy allows you to specify a policy to cache or always pull an image.
|
const imagePullPolicyHelp = `# imagePullPolicy allows you to specify a policy to cache or always pull an image.
|
||||||
@@ -466,7 +464,6 @@ func addImagePullPolicyHelp(values []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addVariablesDoc(values []byte, project *types.Project) []byte {
|
func addVariablesDoc(values []byte, project *types.Project) []byte {
|
||||||
|
|
||||||
lines := strings.Split(string(values), "\n")
|
lines := strings.Split(string(values), "\n")
|
||||||
|
|
||||||
currentService := ""
|
currentService := ""
|
||||||
@@ -550,7 +547,6 @@ func removeNewlinesInsideBrackets(values []byte) []byte {
|
|||||||
replacement = regexp.MustCompile(`\s+`).ReplaceAll(replacement, []byte(" "))
|
replacement = regexp.MustCompile(`\s+`).ReplaceAll(replacement, []byte(" "))
|
||||||
// remove newlines inside brackets
|
// remove newlines inside brackets
|
||||||
return bytes.ReplaceAll(b, matches[1], replacement)
|
return bytes.ReplaceAll(b, matches[1], replacement)
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,8 +603,8 @@ func checkOldLabels(project *types.Project) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helmUpdate runs "helm dependency update" on the output directory.
|
||||||
func helmUpdate(config ConvertOptions) error {
|
func helmUpdate(config ConvertOptions) error {
|
||||||
|
|
||||||
// lookup for "helm" binary
|
// lookup for "helm" binary
|
||||||
fmt.Println(utils.IconInfo, "Updating helm dependencies...")
|
fmt.Println(utils.IconInfo, "Updating helm dependencies...")
|
||||||
helm, err := exec.LookPath("helm")
|
helm, err := exec.LookPath("helm")
|
||||||
@@ -623,8 +619,8 @@ func helmUpdate(config ConvertOptions) error {
|
|||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helmLint runs "helm lint" on the output directory.
|
||||||
func helmLint(config ConvertOptions) error {
|
func helmLint(config ConvertOptions) error {
|
||||||
|
|
||||||
fmt.Println(utils.IconInfo, "Linting...")
|
fmt.Println(utils.IconInfo, "Linting...")
|
||||||
helm, err := exec.LookPath("helm")
|
helm, err := exec.LookPath("helm")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -635,5 +631,4 @@ func helmLint(config ConvertOptions) error {
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
package generator
|
package generator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"katenary/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
goyaml "gopkg.in/yaml.v3"
|
goyaml "gopkg.in/yaml.v3"
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
@@ -26,7 +27,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.
|
// 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) {
|
func NewCronJob(service types.ServiceConfig, chart *HelmChart, appName string) (*CronJob, *RBAC) {
|
||||||
var labels, ok = service.Labels[LABEL_CRONJOB]
|
labels, ok := service.Labels[LABEL_CRONJOB]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ package generator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -10,6 +9,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@@ -32,7 +33,6 @@ type Deployment struct {
|
|||||||
// NewDeployment creates a new Deployment from a compose service. The appName is the name of the application taken from the project name.
|
// 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.
|
// It also creates the Values map that will be used to create the values.yaml file.
|
||||||
func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment {
|
func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment {
|
||||||
|
|
||||||
isMainApp := false
|
isMainApp := false
|
||||||
if mainLabel, ok := service.Labels[LABEL_MAIN_APP]; ok {
|
if mainLabel, ok := service.Labels[LABEL_MAIN_APP]; ok {
|
||||||
main := strings.ToLower(mainLabel)
|
main := strings.ToLower(mainLabel)
|
||||||
@@ -163,7 +163,6 @@ func (d *Deployment) AddIngress(service types.ServiceConfig, appName string) *In
|
|||||||
// AddVolumes adds a volume to the deployment. It does not create the PVC, it only adds the volumes to the deployment.
|
// 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.
|
// 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) {
|
func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||||
|
|
||||||
tobind := map[string]bool{}
|
tobind := map[string]bool{}
|
||||||
if v, ok := service.Labels[LABEL_CM_FILES]; ok {
|
if v, ok := service.Labels[LABEL_CM_FILES]; ok {
|
||||||
binds := []string{}
|
binds := []string{}
|
||||||
@@ -323,7 +322,6 @@ func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) {
|
|||||||
|
|
||||||
// SetEnvFrom sets the environment variables to a configmap. The configmap is created.
|
// SetEnvFrom sets the environment variables to a configmap. The configmap is created.
|
||||||
func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) {
|
func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) {
|
||||||
|
|
||||||
if len(service.Environment) == 0 {
|
if len(service.Environment) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -419,7 +417,6 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *corev1.Container) {
|
func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *corev1.Container) {
|
||||||
|
|
||||||
// get the label for healthcheck
|
// get the label for healthcheck
|
||||||
if v, ok := service.Labels[LABEL_HEALTHCHECK]; ok {
|
if v, ok := service.Labels[LABEL_HEALTHCHECK]; ok {
|
||||||
probes := struct {
|
probes := struct {
|
||||||
@@ -473,7 +470,6 @@ func (d *Deployment) Yaml() ([]byte, error) {
|
|||||||
volumeName = strings.TrimSpace(strings.Replace(content[i], "name: ", "", 1))
|
volumeName = strings.TrimSpace(strings.Replace(content[i], "name: ", "", 1))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if volumeName == "" {
|
if volumeName == "" {
|
||||||
continue
|
continue
|
||||||
@@ -561,6 +557,7 @@ func (d *Deployment) Yaml() ([]byte, error) {
|
|||||||
return []byte(strings.Join(content, "\n")), nil
|
return []byte(strings.Join(content, "\n")), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filename returns the filename of the deployment.
|
||||||
func (d *Deployment) Filename() string {
|
func (d *Deployment) Filename() string {
|
||||||
return d.service.Name + ".deployment.yaml"
|
return d.service.Name + ".deployment.yaml"
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ package generator
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -13,6 +12,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
goyaml "gopkg.in/yaml.v3"
|
goyaml "gopkg.in/yaml.v3"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@@ -24,23 +25,15 @@ import (
|
|||||||
//
|
//
|
||||||
// The Generate function will create the HelmChart object this way:
|
// The Generate function will create the HelmChart object this way:
|
||||||
//
|
//
|
||||||
// 1. Detect the service port name or leave the port number if not found.
|
// - Detect the service port name or leave the port number if not found.
|
||||||
//
|
// - Create a deployment for each service that are not ingnore.
|
||||||
// 2. Create a deployment for each service that are not ingnore.
|
// - Create a service and ingresses for each service that has ports and/or declared ingresses.
|
||||||
//
|
// - Create a PVC or Configmap volumes for each volume.
|
||||||
// 3. Create a service and ingresses for each service that has ports and/or declared ingresses.
|
// - Create init containers for each service which has dependencies to other services.
|
||||||
//
|
// - Create a chart dependencies.
|
||||||
// 4. Create a PVC or Configmap volumes for each volume.
|
// - Create a configmap and secrets from the environment variables.
|
||||||
//
|
// - Merge the same-pod services.
|
||||||
// 5. Create init containers for each service which has dependencies to other services.
|
|
||||||
//
|
|
||||||
// 6. Create a chart dependencies.
|
|
||||||
//
|
|
||||||
// 7. Create a configmap and secrets from the environment variables.
|
|
||||||
//
|
|
||||||
// 8. Merge the same-pod services.
|
|
||||||
func Generate(project *types.Project) (*HelmChart, error) {
|
func Generate(project *types.Project) (*HelmChart, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
appName = project.Name
|
appName = project.Name
|
||||||
deployments = make(map[string]*Deployment, len(project.Services))
|
deployments = make(map[string]*Deployment, len(project.Services))
|
||||||
@@ -226,7 +219,6 @@ func computeNIndent(b []byte) []byte {
|
|||||||
//
|
//
|
||||||
// we now want to replace it with {{ include "foo.labels" . }}, without the label name.
|
// we now want to replace it with {{ include "foo.labels" . }}, without the label name.
|
||||||
func removeReplaceString(b []byte) []byte {
|
func removeReplaceString(b []byte) []byte {
|
||||||
|
|
||||||
// replace all matches with the value of the capture group
|
// replace all matches with the value of the capture group
|
||||||
// and remove all new lines and repeated spaces
|
// and remove all new lines and repeated spaces
|
||||||
b = replaceLabelRegexp.ReplaceAllFunc(b, func(b []byte) []byte {
|
b = replaceLabelRegexp.ReplaceAllFunc(b, func(b []byte) []byte {
|
||||||
@@ -239,6 +231,7 @@ func removeReplaceString(b []byte) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serviceIsMain returns true if the service is the main app.
|
||||||
func serviceIsMain(service types.ServiceConfig) bool {
|
func serviceIsMain(service types.ServiceConfig) bool {
|
||||||
if main, ok := service.Labels[LABEL_MAIN_APP]; ok {
|
if main, ok := service.Labels[LABEL_MAIN_APP]; ok {
|
||||||
return main == "true" || main == "yes" || main == "1"
|
return main == "true" || main == "yes" || main == "1"
|
||||||
@@ -246,6 +239,7 @@ func serviceIsMain(service types.ServiceConfig) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setChartVersion sets the chart version from the service image tag.
|
||||||
func setChartVersion(chart *HelmChart, service types.ServiceConfig) {
|
func setChartVersion(chart *HelmChart, service types.ServiceConfig) {
|
||||||
if chart.Version == "" {
|
if chart.Version == "" {
|
||||||
image := service.Image
|
image := service.Image
|
||||||
@@ -258,6 +252,7 @@ func setChartVersion(chart *HelmChart, service types.ServiceConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fixPorts checks the "ports" label from container and add it to the service.
|
||||||
func fixPorts(service *types.ServiceConfig) error {
|
func fixPorts(service *types.ServiceConfig) error {
|
||||||
// check the "ports" label from container and add it to the service
|
// check the "ports" label from container and add it to the service
|
||||||
if portsLabel, ok := service.Labels[LABEL_PORTS]; ok {
|
if portsLabel, ok := service.Labels[LABEL_PORTS]; ok {
|
||||||
@@ -286,6 +281,7 @@ func fixPorts(service *types.ServiceConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setCronJob creates a cronjob from the service labels.
|
||||||
func setCronJob(service types.ServiceConfig, chart *HelmChart, appName string) *CronJob {
|
func setCronJob(service types.ServiceConfig, chart *HelmChart, appName string) *CronJob {
|
||||||
if _, ok := service.Labels[LABEL_CRONJOB]; !ok {
|
if _, ok := service.Labels[LABEL_CRONJOB]; !ok {
|
||||||
return nil
|
return nil
|
||||||
@@ -318,6 +314,7 @@ func setCronJob(service types.ServiceConfig, chart *HelmChart, appName string) *
|
|||||||
return cronjob
|
return cronjob
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setDependencies sets the dependencies from the service labels.
|
||||||
func setDependencies(chart *HelmChart, service types.ServiceConfig) (bool, error) {
|
func setDependencies(chart *HelmChart, service types.ServiceConfig) (bool, error) {
|
||||||
// helm dependency
|
// helm dependency
|
||||||
if v, ok := service.Labels[LABEL_DEPENDENCIES]; ok {
|
if v, ok := service.Labels[LABEL_DEPENDENCIES]; ok {
|
||||||
@@ -342,6 +339,7 @@ func setDependencies(chart *HelmChart, service types.ServiceConfig) (bool, error
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isIgnored returns true if the service is ignored.
|
||||||
func isIgnored(service types.ServiceConfig) bool {
|
func isIgnored(service types.ServiceConfig) bool {
|
||||||
if v, ok := service.Labels[LABEL_IGNORE]; ok {
|
if v, ok := service.Labels[LABEL_IGNORE]; ok {
|
||||||
return v == "true" || v == "yes" || v == "1"
|
return v == "true" || v == "yes" || v == "1"
|
||||||
@@ -349,6 +347,7 @@ func isIgnored(service types.ServiceConfig) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildVolumes creates the volumes for the service.
|
||||||
func buildVolumes(service types.ServiceConfig, chart *HelmChart, deployments map[string]*Deployment) error {
|
func buildVolumes(service types.ServiceConfig, chart *HelmChart, deployments map[string]*Deployment) error {
|
||||||
appName := chart.Name
|
appName := chart.Name
|
||||||
for _, v := range service.Volumes {
|
for _, v := range service.Volumes {
|
||||||
@@ -437,6 +436,7 @@ func buildVolumes(service types.ServiceConfig, chart *HelmChart, deployments map
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generateConfigMapsAndSecrets creates the configmaps and secrets from the environment variables.
|
||||||
func generateConfigMapsAndSecrets(project *types.Project, chart *HelmChart) error {
|
func generateConfigMapsAndSecrets(project *types.Project, chart *HelmChart) error {
|
||||||
appName := chart.Name
|
appName := chart.Name
|
||||||
for _, s := range project.Services {
|
for _, s := range project.Services {
|
||||||
@@ -498,6 +498,7 @@ func generateConfigMapsAndSecrets(project *types.Project, chart *HelmChart) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// samePodVolume returns true if the volume is already in the target deployment.
|
||||||
func samePodVolume(service types.ServiceConfig, v types.ServiceVolumeConfig, deployments map[string]*Deployment) bool {
|
func samePodVolume(service types.ServiceConfig, v types.ServiceVolumeConfig, deployments map[string]*Deployment) bool {
|
||||||
// if the service has volumes, and it has "same-pod" label
|
// if the service has volumes, and it has "same-pod" label
|
||||||
// - get the target deployment
|
// - get the target deployment
|
||||||
@@ -541,6 +542,7 @@ func samePodVolume(service types.ServiceConfig, v types.ServiceVolumeConfig, dep
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSharedConf sets the shared configmap to the service.
|
||||||
func setSharedConf(service types.ServiceConfig, chart *HelmChart, deployments map[string]*Deployment) {
|
func setSharedConf(service types.ServiceConfig, chart *HelmChart, deployments map[string]*Deployment) {
|
||||||
// if the service has the "shared-conf" label, we need to add the configmap
|
// 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
|
// to the chart and add the env vars to the service
|
||||||
@@ -583,5 +585,4 @@ func setSharedConf(service types.ServiceConfig, chart *HelmChart, deployments ma
|
|||||||
target.Spec.Template.Spec.Containers[i] = c
|
target.Spec.Template.Spec.Containers[i] = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
package generator
|
package generator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"katenary/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
goyaml "gopkg.in/yaml.v3"
|
goyaml "gopkg.in/yaml.v3"
|
||||||
networkv1 "k8s.io/api/networking/v1"
|
networkv1 "k8s.io/api/networking/v1"
|
||||||
@@ -21,7 +22,6 @@ type Ingress struct {
|
|||||||
|
|
||||||
// NewIngress creates a new Ingress from a compose service.
|
// NewIngress creates a new Ingress from a compose service.
|
||||||
func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress {
|
func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress {
|
||||||
|
|
||||||
appName := Chart.Name
|
appName := Chart.Name
|
||||||
|
|
||||||
// parse the KATENARY_PREFIX/ingress label from the service
|
// parse the KATENARY_PREFIX/ingress label from the service
|
||||||
@@ -173,7 +173,6 @@ func (ingress *Ingress) Yaml() ([]byte, error) {
|
|||||||
out = append(out, `{{- end -}}`)
|
out = append(out, `{{- end -}}`)
|
||||||
ret = []byte(strings.Join(out, "\n"))
|
ret = []byte(strings.Join(out, "\n"))
|
||||||
return ret, nil
|
return ret, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ingress *Ingress) Filename() string {
|
func (ingress *Ingress) Filename() string {
|
||||||
|
@@ -4,13 +4,14 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/utils"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -139,7 +140,6 @@ func generateTableHeaderSeparator(maxNameLength, maxDescriptionLength, maxTypeLe
|
|||||||
|
|
||||||
// GetLabelHelpFor returns the help for a specific label.
|
// GetLabelHelpFor returns the help for a specific label.
|
||||||
func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
||||||
|
|
||||||
help, ok := labelFullHelp[labelname]
|
help, ok := labelFullHelp[labelname]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "No help available for " + labelname + "."
|
return "No help available for " + labelname + "."
|
||||||
@@ -225,5 +225,4 @@ Type: {{ .Help.Type }}
|
|||||||
Example:
|
Example:
|
||||||
{{ .Help.Example }}
|
{{ .Help.Example }}
|
||||||
`
|
`
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,8 @@ const (
|
|||||||
ServiceLabel
|
ServiceLabel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 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.
|
||||||
func GetLabels(serviceName, appName string) map[string]string {
|
func GetLabels(serviceName, appName string) map[string]string {
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
KATENARY_PREFIX + "component": serviceName,
|
KATENARY_PREFIX + "component": serviceName,
|
||||||
@@ -24,6 +26,8 @@ func GetLabels(serviceName, appName string) map[string]string {
|
|||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMatchLabels returns the matchLabels for a service. It uses the appName to replace the __replace__ in the labels.
|
||||||
|
// This is used to generate the matchLabels in the templates.
|
||||||
func GetMatchLabels(serviceName, appName string) map[string]string {
|
func GetMatchLabels(serviceName, appName string) map[string]string {
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
KATENARY_PREFIX + "component": serviceName,
|
KATENARY_PREFIX + "component": serviceName,
|
||||||
|
@@ -3,17 +3,20 @@ package generator
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/utils"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ DataMap = (*Secret)(nil)
|
var (
|
||||||
var _ Yaml = (*Secret)(nil)
|
_ DataMap = (*Secret)(nil)
|
||||||
|
_ Yaml = (*Secret)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
// Secret is a kubernetes Secret.
|
// Secret is a kubernetes Secret.
|
||||||
//
|
//
|
||||||
@@ -78,7 +81,6 @@ func (s *Secret) SetData(data map[string]string) {
|
|||||||
for key, value := range data {
|
for key, value := range data {
|
||||||
s.AddData(key, value)
|
s.AddData(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddData adds a key value pair to the secret.
|
// AddData adds a key value pair to the secret.
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
package generator
|
package generator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"katenary/utils"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -22,7 +23,6 @@ type Service struct {
|
|||||||
|
|
||||||
// NewService creates a new Service from a compose service.
|
// NewService creates a new Service from a compose service.
|
||||||
func NewService(service types.ServiceConfig, appName string) *Service {
|
func NewService(service types.ServiceConfig, appName string) *Service {
|
||||||
|
|
||||||
ports := []v1.ServicePort{}
|
ports := []v1.ServicePort{}
|
||||||
|
|
||||||
s := &Service{
|
s := &Service{
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
package generator
|
package generator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"katenary/utils"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"katenary/utils"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
@@ -59,7 +60,6 @@ func (v *VolumeClaim) Yaml() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
volumeName := v.volumeName
|
volumeName := v.volumeName
|
||||||
out, err := yaml.Marshal(v)
|
out, err := yaml.Marshal(v)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
// Parse compose files and return a project. The project is parsed with dotenv, osenv and profiles.
|
// Parse compose files and return a project. The project is parsed with dotenv, osenv and profiles.
|
||||||
func Parse(profiles []string, dockerComposeFile ...string) (*types.Project, error) {
|
func Parse(profiles []string, dockerComposeFile ...string) (*types.Project, error) {
|
||||||
|
|
||||||
cli.DefaultOverrideFileNames = append(cli.DefaultOverrideFileNames, "compose.katenary.yaml")
|
cli.DefaultOverrideFileNames = append(cli.DefaultOverrideFileNames, "compose.katenary.yaml")
|
||||||
|
|
||||||
if len(dockerComposeFile) == 0 {
|
if len(dockerComposeFile) == 0 {
|
||||||
@@ -23,8 +22,6 @@ func Parse(profiles []string, dockerComposeFile ...string) (*types.Project, erro
|
|||||||
cli.WithNormalization(true),
|
cli.WithNormalization(true),
|
||||||
cli.WithInterpolation(true),
|
cli.WithInterpolation(true),
|
||||||
cli.WithResolvedPaths(false),
|
cli.WithResolvedPaths(false),
|
||||||
|
|
||||||
//cli.WithResolvedPaths(true),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -14,8 +14,10 @@ import (
|
|||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
var exe, _ = os.Executable()
|
var (
|
||||||
var Version = "master" // reset by cmd/main.go
|
exe, _ = os.Executable()
|
||||||
|
Version = "master" // reset by cmd/main.go
|
||||||
|
)
|
||||||
|
|
||||||
// Asset is a github asset from release url.
|
// Asset is a github asset from release url.
|
||||||
type Asset struct {
|
type Asset struct {
|
||||||
@@ -25,7 +27,6 @@ type Asset struct {
|
|||||||
|
|
||||||
// CheckLatestVersion check katenary latest version from release and propose to download it
|
// CheckLatestVersion check katenary latest version from release and propose to download it
|
||||||
func CheckLatestVersion() (string, []Asset, error) {
|
func CheckLatestVersion() (string, []Asset, error) {
|
||||||
|
|
||||||
githuburl := "https://api.github.com/repos/metal3d/katenary/releases/latest"
|
githuburl := "https://api.github.com/repos/metal3d/katenary/releases/latest"
|
||||||
// Create a HTTP client with 1s timeout
|
// Create a HTTP client with 1s timeout
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
@@ -45,7 +46,7 @@ func CheckLatestVersion() (string, []Asset, error) {
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
// Get tag_name from the json response
|
// Get tag_name from the json response
|
||||||
var release = struct {
|
release := struct {
|
||||||
TagName string `json:"tag_name"`
|
TagName string `json:"tag_name"`
|
||||||
Assets []Asset `json:"assets"`
|
Assets []Asset `json:"assets"`
|
||||||
PreRelease bool `json:"prerelease"`
|
PreRelease bool `json:"prerelease"`
|
||||||
@@ -57,19 +58,19 @@ func CheckLatestVersion() (string, []Asset, error) {
|
|||||||
|
|
||||||
// if it's a prerelease, don't update
|
// if it's a prerelease, don't update
|
||||||
if release.PreRelease {
|
if release.PreRelease {
|
||||||
return "", nil, errors.New("Prerelease detected, not updating")
|
return "", nil, errors.New("prerelease detected, not updating")
|
||||||
}
|
}
|
||||||
|
|
||||||
// no tag, don't update
|
// no tag, don't update
|
||||||
if release.TagName == "" {
|
if release.TagName == "" {
|
||||||
return "", nil, errors.New("No release found")
|
return "", nil, errors.New("no release found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// compare the current version, if the current version is the same or lower than the latest version, don't update
|
// compare the current version, if the current version is the same or lower than the latest version, don't update
|
||||||
versions := []string{Version, release.TagName}
|
versions := []string{Version, release.TagName}
|
||||||
semver.Sort(versions)
|
semver.Sort(versions)
|
||||||
if versions[1] == Version {
|
if versions[1] == Version {
|
||||||
return "", nil, errors.New("Current version is the latest version")
|
return "", nil, errors.New("current version is the latest version")
|
||||||
}
|
}
|
||||||
|
|
||||||
return release.TagName, release.Assets, nil
|
return release.TagName, release.Assets, nil
|
||||||
@@ -77,7 +78,6 @@ func CheckLatestVersion() (string, []Asset, error) {
|
|||||||
|
|
||||||
// DownloadLatestVersion will download the latest version of katenary.
|
// DownloadLatestVersion will download the latest version of katenary.
|
||||||
func DownloadLatestVersion(assets []Asset) error {
|
func DownloadLatestVersion(assets []Asset) error {
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
os.Rename(exe+".old", exe)
|
os.Rename(exe+".old", exe)
|
||||||
@@ -117,7 +117,7 @@ func DownloadLatestVersion(assets []Asset) error {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fmt.Println("Unsupported OS")
|
fmt.Println("Unsupported OS")
|
||||||
err = errors.New("Unsupported OS")
|
err = errors.New("unsupported OS")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -138,7 +138,7 @@ func DownloadFile(url, exe string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
fp, err := os.OpenFile(exe, os.O_WRONLY|os.O_CREATE, 0755)
|
fp, err := os.OpenFile(exe, os.O_WRONLY|os.O_CREATE, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -8,17 +8,17 @@ type Icon string
|
|||||||
// Icons used in katenary.
|
// Icons used in katenary.
|
||||||
const (
|
const (
|
||||||
IconSuccess Icon = "✅"
|
IconSuccess Icon = "✅"
|
||||||
IconFailure = "❌"
|
IconFailure Icon = "❌"
|
||||||
IconWarning = "⚠️'"
|
IconWarning Icon = "⚠️'"
|
||||||
IconNote = "📝"
|
IconNote Icon = "📝"
|
||||||
IconWorld = "🌐"
|
IconWorld Icon = "🌐"
|
||||||
IconPlug = "🔌"
|
IconPlug Icon = "🔌"
|
||||||
IconPackage = "📦"
|
IconPackage Icon = "📦"
|
||||||
IconCabinet = "🗄️"
|
IconCabinet Icon = "🗄️"
|
||||||
IconInfo = "❕"
|
IconInfo Icon = "❕"
|
||||||
IconSecret = "🔒"
|
IconSecret Icon = "🔒"
|
||||||
IconConfig = "🔧"
|
IconConfig Icon = "🔧"
|
||||||
IconDependency = "🔗"
|
IconDependency Icon = "🔗"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Warn prints a warning message
|
// Warn prints a warning message
|
||||||
|
@@ -90,7 +90,6 @@ func GetContainerByName(name string, containers []corev1.Container) (*corev1.Con
|
|||||||
|
|
||||||
// GetContainerByName returns a container by name and its index in the array.
|
// GetContainerByName returns a container by name and its index in the array.
|
||||||
func TplValue(serviceName, variable string, pipes ...string) string {
|
func TplValue(serviceName, variable string, pipes ...string) string {
|
||||||
|
|
||||||
if len(pipes) == 0 {
|
if len(pipes) == 0 {
|
||||||
return `{{ tpl .Values.` + serviceName + `.` + variable + ` $ }}`
|
return `{{ tpl .Values.` + serviceName + `.` + variable + ` $ }}`
|
||||||
} else {
|
} else {
|
||||||
@@ -108,8 +107,8 @@ func PathToName(path string) string {
|
|||||||
if path[0] == '/' || path[0] == '.' {
|
if path[0] == '/' || path[0] == '.' {
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
}
|
}
|
||||||
path = strings.Replace(path, "/", "_", -1)
|
path = strings.ReplaceAll(path, "/", "_")
|
||||||
path = strings.Replace(path, ".", "_", -1)
|
path = strings.ReplaceAll(path, ".", "_")
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +129,9 @@ func GetValuesFromLabel(service types.ServiceConfig, LabelValues string) map[str
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, value := range labelContent {
|
for _, value := range labelContent {
|
||||||
switch value.(type) {
|
switch val := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
descriptions[value.(string)] = nil
|
descriptions[val] = nil
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
for k, v := range value.(map[string]interface{}) {
|
for k, v := range value.(map[string]interface{}) {
|
||||||
descriptions[k] = &EnvConfig{Service: service, Description: v.(string)}
|
descriptions[k] = &EnvConfig{Service: service, Description: v.(string)}
|
||||||
|
Reference in New Issue
Block a user