This prepares the next release. We need to support the compose v2 syntax as soon as possible to avoid accumulating technical debt.
201 lines
5.6 KiB
Go
201 lines
5.6 KiB
Go
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/compose-spec/compose-go/v2/types"
|
|
"github.com/mitchellh/go-wordwrap"
|
|
"github.com/thediveo/netdb"
|
|
"gopkg.in/yaml.v3"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"katenary.io/internal/logger"
|
|
)
|
|
|
|
// DirectoryPermission is the default values for permissions apply to created directories.
|
|
const DirectoryPermission = 0o755
|
|
|
|
// TplName returns the name of the kubernetes resource as a template string.
|
|
// It is used in the templates and defined in _helper.tpl file.
|
|
func TplName(serviceName, appname string, suffix ...string) string {
|
|
if len(suffix) > 0 {
|
|
suffix[0] = "-" + suffix[0]
|
|
}
|
|
for i, s := range suffix {
|
|
// replae all "_" with "-"
|
|
suffix[i] = strings.ReplaceAll(s, "_", "-")
|
|
}
|
|
serviceName = strings.ReplaceAll(serviceName, "_", "-")
|
|
return `{{ include "` + appname + `.fullname" . }}-` + serviceName + strings.Join(suffix, "-")
|
|
}
|
|
|
|
// Int32Ptr returns a pointer to an int32.
|
|
func Int32Ptr(i int32) *int32 { return &i }
|
|
|
|
// StrPtr returns a pointer to a string.
|
|
func StrPtr(s string) *string { return &s }
|
|
|
|
// CountStartingSpaces counts the number of spaces at the beginning of a string.
|
|
func CountStartingSpaces(line string) int {
|
|
count := 0
|
|
for _, char := range line {
|
|
if char == ' ' {
|
|
count++
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
// GetKind returns the kind of the resource from the file path.
|
|
func GetKind(path string) (kind string) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
kind = ""
|
|
}
|
|
}()
|
|
filename := filepath.Base(path)
|
|
parts := strings.Split(filename, ".")
|
|
if len(parts) == 2 {
|
|
kind = parts[0]
|
|
} else {
|
|
kind = strings.Split(path, ".")[1]
|
|
}
|
|
return kind
|
|
}
|
|
|
|
// Wrap wraps a string with a string above and below. It will respect the indentation of the src string.
|
|
func Wrap(src, above, below string) string {
|
|
spaces := strings.Repeat(" ", CountStartingSpaces(src))
|
|
return spaces + above + "\n" + src + "\n" + spaces + below
|
|
}
|
|
|
|
// GetServiceNameByPort returns the service name for a port. It the service name is not found, it returns an empty string.
|
|
func GetServiceNameByPort(port int) string {
|
|
name := ""
|
|
info := netdb.ServiceByPort(port, "tcp")
|
|
if info != nil {
|
|
name = info.Name
|
|
}
|
|
return name
|
|
}
|
|
|
|
// GetContainerByName returns a container by name and its index in the array. It returns nil, -1 if not found.
|
|
func GetContainerByName(name string, containers []corev1.Container) (*corev1.Container, int) {
|
|
for index, c := range containers {
|
|
if c.Name == name {
|
|
return &c, index
|
|
}
|
|
}
|
|
return nil, -1
|
|
}
|
|
|
|
// TplValue returns a string that can be used in a template to access a value from the values file.
|
|
func TplValue(serviceName, variable string, pipes ...string) string {
|
|
if len(pipes) == 0 {
|
|
return `{{ tpl .Values.` + serviceName + `.` + variable + ` $ }}`
|
|
} else {
|
|
return `{{ tpl .Values.` + serviceName + `.` + variable + ` $ | ` + strings.Join(pipes, " | ") + ` }}`
|
|
}
|
|
}
|
|
|
|
// PathToName converts a path to a kubernetes complient name.
|
|
func PathToName(path string) string {
|
|
if len(path) == 0 {
|
|
return ""
|
|
}
|
|
|
|
path = filepath.Clean(path)
|
|
if path[0] == '/' || path[0] == '.' {
|
|
path = path[1:]
|
|
}
|
|
path = strings.ReplaceAll(path, "_", "-")
|
|
path = strings.ReplaceAll(path, "/", "-")
|
|
path = strings.ReplaceAll(path, ".", "-")
|
|
path = strings.ToLower(path)
|
|
return path
|
|
}
|
|
|
|
// EnvConfig is a struct to hold the description of an environment variable.
|
|
type EnvConfig struct {
|
|
Service types.ServiceConfig
|
|
Description string
|
|
}
|
|
|
|
// GetValuesFromLabel returns a map of values from a label.
|
|
func GetValuesFromLabel(service types.ServiceConfig, LabelValues string) map[string]*EnvConfig {
|
|
descriptions := make(map[string]*EnvConfig)
|
|
if v, ok := service.Labels[LabelValues]; ok {
|
|
labelContent := []any{}
|
|
err := yaml.Unmarshal([]byte(v), &labelContent)
|
|
if err != nil {
|
|
log.Printf("Error parsing label %s: %s", v, err)
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for _, value := range labelContent {
|
|
switch value := value.(type) {
|
|
case string:
|
|
descriptions[value] = nil
|
|
case map[string]any:
|
|
for k, v := range value {
|
|
descriptions[k] = &EnvConfig{Service: service, Description: v.(string)}
|
|
}
|
|
case map[any]any:
|
|
for k, v := range value {
|
|
descriptions[k.(string)] = &EnvConfig{Service: service, Description: v.(string)}
|
|
}
|
|
default:
|
|
log.Fatalf("Unknown type in label: %s %T", LabelValues, value)
|
|
}
|
|
}
|
|
}
|
|
return descriptions
|
|
}
|
|
|
|
// WordWrap wraps a string to a given line width. Warning: it may break the string. You need to check the result.
|
|
func WordWrap(text string, lineWidth int) string {
|
|
return wordwrap.WrapString(text, uint(lineWidth))
|
|
}
|
|
|
|
// Confirm asks a question and returns true if the answer is y.
|
|
func Confirm(question string, icon ...logger.Icon) bool {
|
|
if len(icon) > 0 {
|
|
fmt.Printf("%s %s [y/N] ", icon[0], question)
|
|
} else {
|
|
fmt.Print(question + " [y/N] ")
|
|
}
|
|
var response string
|
|
if _, err := fmt.Scanln(&response); err != nil {
|
|
log.Fatalf("Error parsing response: %s", err.Error())
|
|
}
|
|
return strings.ToLower(response) == "y"
|
|
}
|
|
|
|
// EncodeBasicYaml encodes a basic yaml from an interface.
|
|
func EncodeBasicYaml(data any) ([]byte, error) {
|
|
buf := bytes.NewBuffer(nil)
|
|
enc := yaml.NewEncoder(buf)
|
|
enc.SetIndent(2)
|
|
err := enc.Encode(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// FixedResourceName returns a resource name without underscores to respect the kubernetes naming convention.
|
|
func FixedResourceName(name string) string {
|
|
return strings.ReplaceAll(name, "_", "-")
|
|
}
|
|
|
|
// AsResourceName returns a resource name with underscores to respect the kubernetes naming convention.
|
|
// It's the opposite of FixedResourceName.
|
|
func AsResourceName(name string) string {
|
|
return strings.ReplaceAll(name, "-", "_")
|
|
}
|