Go to Katenary V3
This is the next-gen of Katenary
This commit is contained in:
2
utils/doc.go
Normal file
2
utils/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Utils package provides some utility functions used in katenary. It defines some constants and functions used in the whole project.
|
||||
package utils
|
26
utils/hash.go
Normal file
26
utils/hash.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// HashComposefiles returns a hash of the compose files.
|
||||
func HashComposefiles(files []string) (string, error) {
|
||||
sort.Strings(files) // ensure the order is always the same
|
||||
sha := sha1.New()
|
||||
for _, file := range files {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := io.Copy(sha, f); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return hex.EncodeToString(sha.Sum(nil)), nil
|
||||
}
|
31
utils/icons.go
Normal file
31
utils/icons.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Icon is a unicode icon
|
||||
type Icon string
|
||||
|
||||
// Icons used in katenary.
|
||||
const (
|
||||
IconSuccess Icon = "✅"
|
||||
IconFailure = "❌"
|
||||
IconWarning = "⚠️'"
|
||||
IconNote = "📝"
|
||||
IconWorld = "🌐"
|
||||
IconPlug = "🔌"
|
||||
IconPackage = "📦"
|
||||
IconCabinet = "🗄️"
|
||||
IconInfo = "❕"
|
||||
IconSecret = "🔒"
|
||||
IconConfig = "🔧"
|
||||
IconDependency = "🔗"
|
||||
)
|
||||
|
||||
// Warn prints a warning message
|
||||
func Warn(msg ...interface{}) {
|
||||
orange := "\033[38;5;214m"
|
||||
reset := "\033[0m"
|
||||
fmt.Print(IconWarning, orange, " ")
|
||||
fmt.Print(msg...)
|
||||
fmt.Println(reset)
|
||||
}
|
163
utils/utils.go
Normal file
163
utils/utils.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"log"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
"github.com/thediveo/netdb"
|
||||
"gopkg.in/yaml.v3"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// 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]
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// WrapBytes wraps a byte array with a byte array above and below. It will respect the indentation of the src string.
|
||||
func WrapBytes(src, above, below []byte) []byte {
|
||||
return []byte(Wrap(string(src), string(above), string(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
|
||||
}
|
||||
|
||||
// GetContainerByName returns a container by name and its index in the array.
|
||||
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.Replace(path, "/", "_", -1)
|
||||
path = strings.Replace(path, ".", "_", -1)
|
||||
return path
|
||||
}
|
||||
|
||||
// EnvConfig is a struct to hold the description of an environment variable.
|
||||
type EnvConfig struct {
|
||||
Description string
|
||||
Service types.ServiceConfig
|
||||
}
|
||||
|
||||
// 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.(type) {
|
||||
case string:
|
||||
descriptions[value.(string)] = nil
|
||||
case map[string]interface{}:
|
||||
for k, v := range value.(map[string]interface{}) {
|
||||
descriptions[k] = &EnvConfig{Service: service, Description: v.(string)}
|
||||
}
|
||||
case map[interface{}]interface{}:
|
||||
for k, v := range value.(map[interface{}]interface{}) {
|
||||
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))
|
||||
}
|
||||
|
||||
func MapKeys(m map[string]interface{}) []string {
|
||||
keys := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
Reference in New Issue
Block a user