package main import ( "fmt" "io/fs" "os" "strings" "text/template" ) import "embed" import sprig "github.com/Masterminds/sprig/v3" // This provides most Helm functions import "github.com/goccy/go-yaml" // This provides most Helm functions //go:embed templates/* var templateFS embed.FS func NewTemplate() *template.Template { tmpl := template.New("") // Combine sprig functions with custom functions funcMap := template.FuncMap{} // Add all sprig functions for name, fn := range sprig.FuncMap() { funcMap[name] = fn } // Add any custom functions you want customFuncs := template.FuncMap{ "toYaml": func(v interface{}) string { data, err := yaml.Marshal(v) if err != nil { return "" } return string(data) }, } // Merge custom functions for name, fn := range customFuncs { funcMap[name] = fn } // Add the function map to the template tmpl = tmpl.Funcs(funcMap) return tmpl } func showContents(files fs.FS) { entries, err := fs.ReadDir(files, ".") if err != nil { panic(err) } for _, entry := range entries { if entry.Type().IsDir() { subdir, err := fs.Sub(files, entry.Name()) if err != nil { panic(err) } showContents(subdir) } } } type PolicyTemplates struct { templates *template.Template } func NewPolicyTemplates() (*PolicyTemplates, error) { showContents(templateFS) // Parse all templates at once from the embedded FS tmpl := NewTemplate() err := loadTemplatesAll(tmpl) if err != nil { return nil, err } return &PolicyTemplates{templates: tmpl}, err } func loadTemplatesAll(tmpl *template.Template) error { return fs.WalkDir(templateFS, ".", func(path string, d os.DirEntry, err error) error { if strings.HasSuffix(path, ".yaml") { data, err := fs.ReadFile(templateFS, path) if err != nil { return err } fmt.Fprintf(os.Stderr, "Loading template %s\n", path) _, err = tmpl.New(path).Option("missingkey=error").Parse(string(data)) if err != nil { return err } } return nil }) } func (t *PolicyTemplates) NamespaceTemplates(policyType string, capabilities []string) []*template.Template { res := make([]*template.Template, 0) tmpl := t.templates.Lookup(fmt.Sprintf("templates/%s/namespace/namespace.yaml", policyType)) if tmpl != nil { res = append(res, tmpl) } for _, capability := range capabilities { tmpl := t.templates.Lookup(fmt.Sprintf("templates/%s/namespace/%s.yaml", policyType, capability)) if tmpl != nil { res = append(res, tmpl) } } return res } func (t *PolicyTemplates) ApplicationTemplate(policyType string) *template.Template { tmpl := t.templates.Lookup(fmt.Sprintf("templates/%s/pod/pod.yaml", policyType)) return tmpl } func (t *PolicyTemplates) PredefineApplicationPolicyTemplate(policyType string, predefined string) *template.Template { tmpl := t.templates.Lookup(fmt.Sprintf("templates/%s/pod/%s.yaml", policyType, predefined)) return tmpl }