Files
truecharts/clustertool/pkg/charts/chartFile/chart_file.go
T
Kjeld Schouten 1c28a12789 chore: fix links
2025-09-07 14:26:19 +02:00

235 lines
7.3 KiB
Go

package chartFile
import (
"bytes"
"fmt"
"os"
"github.com/go-playground/validator/v10"
"github.com/trueforge-org/truecharts/clustertool/pkg/helper"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/v2"
)
const (
minHelmVersion = "3.14"
maxHelmVersion = "3.17"
minKubeVersion = "1.24.0"
maxKubeVersion = "1.32.0"
kubeVersion = ">=1.24.0-0"
apiVersion = "v2"
chartType = "application"
maintainerName = "TrueCharts"
maintainerEmail = "info@truecharts.org"
maintainerURL = "https://truecharts.org"
defaultCategory = "unsorted"
defaultAppVersion = "unknown"
defaultDescription = "No description provided."
defaultHome = "https://truecharts.org"
defaultIcon = "https://github.com/trueforge-org/truecharts/blob/main/website/static/svg/logo.svg"
supportUrl = `- name: support
url: https://discord.com/invite/tVsPTHWTtr`
)
var validate *validator.Validate
// Maintainer represents a maintainer of the Helm chart.
type Maintainer struct {
Name string `yaml:"name" validate:"required"`
Email string `yaml:"email"`
URL string `yaml:"url" validate:"required"`
}
// Dependency represents a dependency of the Helm chart.
type Dependency struct {
Name string `yaml:"name" validate:"required"`
Version string `yaml:"version" validate:"required"`
Repository string `yaml:"repository" validate:"required"`
Condition string `yaml:"condition"`
Alias string `yaml:"alias"`
Tags []string `yaml:"tags"`
ImportValues []string `yaml:"import-values"`
}
// ChartMetadata represents the metadata structure in Chart.yaml.
type ChartMetadata struct {
Annotations map[string]string `yaml:"annotations"`
APIVersion string `yaml:"apiVersion" validate:"required"`
AppVersion string `yaml:"appVersion" validate:"required"`
Dependencies []Dependency `yaml:"dependencies"`
Deprecated bool `yaml:"deprecated"`
Description string `yaml:"description" validate:"required"`
Home string `yaml:"home" validate:"required"`
Icon string `yaml:"icon" validate:"required"`
Keywords []string `yaml:"keywords"`
KubeVersion string `yaml:"kubeVersion" validate:"required"`
Maintainers []Maintainer `yaml:"maintainers" validate:"required,dive"`
Name string `yaml:"name" validate:"required"`
Sources []string `yaml:"sources"`
Type string `yaml:"type"`
Version string `yaml:"version" validate:"required"`
// Add other fields as needed
}
// HelmChart represents the entire Chart.yaml structure.
type HelmChart struct {
K *koanf.Koanf
Metadata ChartMetadata `yaml:"metadata" validate:"required,dive"`
// Add other fields as needed
}
func NewHelmChart() *HelmChart {
return &HelmChart{
K: koanf.New("."),
}
}
// LoadFromFile loads values from a YAML file into the HelmChart struct.
func (h *HelmChart) LoadFromFile(filename string) error {
// Load YAML file using koanf
if err := h.K.Load(file.Provider(filename), yaml.Parser()); err != nil {
return fmt.Errorf("error loading from file %s: %v", filename, err)
}
// Unmarshal the data into the HelmChart struct
if err := h.K.Unmarshal("", &h.Metadata); err != nil {
return fmt.Errorf("error unmarshalling data: %v", err)
}
// Set default values for fields if they are not set or empty
h.setDefaultValues()
// Initialize validator
validate = validator.New(validator.WithRequiredStructEnabled())
if err := validate.Struct(h.Metadata); err != nil {
return fmt.Errorf("chart.yaml validation error: %v", err)
}
return nil
}
// setDefaultValues sets default values for fields in ChartMetadata if they are not set or empty.
func (h *HelmChart) setDefaultValues() {
h.setDeprecation()
h.setApiVersion(apiVersion)
h.setKubeVersion(kubeVersion)
h.setType(chartType)
h.setAppVersion(defaultAppVersion)
h.setDescription(defaultDescription)
h.setIcon(defaultIcon)
h.setHome(defaultHome)
h.setMaintainers(Maintainer{
Name: maintainerName,
Email: maintainerEmail,
URL: maintainerURL,
})
// Make sure annotations is not nil
if h.Metadata.Annotations == nil {
h.Metadata.Annotations = make(map[string]string)
}
h.setAnnotation("truecharts.org/category", defaultCategory, false)
h.setAnnotation("truecharts.org/min_helm_version", minHelmVersion, true)
h.setAnnotation("truecharts.org/max_helm_version", maxHelmVersion, true)
h.setAnnotation("truecharts.org/min_kubernetes_version", minKubeVersion, true)
h.setAnnotation("truecharts.org/max_kubernetes_version", maxKubeVersion, true)
h.setAnnotation("artifacthub.io/links", supportUrl, true)
// Set default values for other fields as needed
}
// SaveToFile saves the Helm chart metadata back to the Chart.yaml file.
func (h *HelmChart) SaveToFile(filename string) error {
// Initialize validator
validate = validator.New(validator.WithRequiredStructEnabled())
if err := validate.Struct(h.Metadata); err != nil {
return fmt.Errorf("chart.yaml validation error: %v", err)
}
var configBytes bytes.Buffer
err := helper.MarshalYaml(&configBytes, h.Metadata)
if err != nil {
return fmt.Errorf("error encoding data: %v", err)
}
// Write the configuration to the file using os.WriteFile
err = os.WriteFile(filename, configBytes.Bytes(), 0644)
if err != nil {
return fmt.Errorf("error writing to file %s: %v", filename, err)
}
return nil
}
// setAnnotation sets the annotation key to value if it is not set or empty or force is true.
func (h *HelmChart) setAnnotation(key, value string, force bool) {
if a, ok := h.Metadata.Annotations[key]; !ok || a == "" || force {
h.Metadata.Annotations[key] = value
}
}
// setDeprecation sets the deprecation field to false if it is not set.
func (h *HelmChart) setDeprecation() {
if !h.Metadata.Deprecated {
h.Metadata.Deprecated = false
}
}
// setIcon sets the icon field to icon if it is not set or empty.
func (h *HelmChart) setIcon(icon string) {
if h.Metadata.Icon == "" {
h.Metadata.Icon = icon
}
}
// setHome sets the home field to home if it is not set or empty.
func (h *HelmChart) setHome(home string) {
if h.Metadata.Home == "" {
h.Metadata.Home = home
}
}
// setDescription sets the description field to description if it is not set or empty.
func (h *HelmChart) setDescription(description string) {
if h.Metadata.Description == "" {
h.Metadata.Description = description
}
}
// setAppVersion sets the appVersion field to appVersion if it is not set or empty.
func (h *HelmChart) setAppVersion(appVersion string) {
if h.Metadata.AppVersion == "" {
h.Metadata.AppVersion = appVersion
}
}
// setType sets the type field to cType if it is not set or empty.
func (h *HelmChart) setType(cType string) {
if h.Metadata.Type == "" {
h.Metadata.Type = cType
}
}
// setApiVersion sets the apiVersion field to apiVersion
func (h *HelmChart) setApiVersion(apiVersion string) {
h.Metadata.APIVersion = apiVersion
}
// setKubeVersion sets the kubeVersion field to kubeVersion
func (h *HelmChart) setKubeVersion(kubeVersion string) {
h.Metadata.KubeVersion = kubeVersion
}
// setMaintainers sets the maintainers field to maintainers
func (h *HelmChart) setMaintainers(maintainers Maintainer) {
h.Metadata.Maintainers = make([]Maintainer, 1)
h.Metadata.Maintainers[0] = maintainers
}