policy-generator/cmd/policygen/templates.go

127 lines
2.9 KiB
Go

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 {
fmt.Fprintf(os.Stderr, "entry %s %s\n", entry.Name(), entry.Type())
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/pod/%s/%s.yaml", policyType, predefined))
return tmpl
}