diff --git a/pkg/plugins/pyjinja2/pyjinja2.go b/pkg/plugins/pyjinja2/pyjinja2.go new file mode 100644 index 0000000..fe823f2 --- /dev/null +++ b/pkg/plugins/pyjinja2/pyjinja2.go @@ -0,0 +1,121 @@ +package main + +import ( + "encoding/json" + "fmt" + + makeshift "git.towk2.me/towk/makeshift/pkg" + "git.towk2.me/towk/makeshift/pkg/storage" + jinja2 "github.com/kluctl/kluctl/lib/go-jinja2" + "github.com/rs/zerolog/log" +) + +type Jinja2 struct{} + +func (p *Jinja2) Name() string { return "pyjinja2" } +func (p *Jinja2) Version() string { return "v0.0.1-alpha" } +func (p *Jinja2) Description() string { + return "Renders Jinja 2 templates using embedded Python renderer" +} +func (p *Jinja2) Metadata() makeshift.Metadata { + return makeshift.Metadata{ + "author": map[string]any{ + "name": "David J. Allen", + "email": "davidallendj@gmail.com", + "links": []string{ + "https://github.com/davidallendj", + "https://git.towk2.me/towk", + }, + }, + } +} + +func (p *Jinja2) Init() error { + // nothing to initialize + log.Debug().Str("plugin", p.Name()).Msg("pyjinja2.Init()") + return nil +} + +func (p *Jinja2) Run(store storage.KVStore, args []string) error { + // render the files using Jinja 2 from args + var ( + mappings struct { + Data map[string]any `json:"data"` + } + profiles any // makeshift.ProfileMap + input any // []byte + output string + err error + ) + log.Debug(). + Str("plugin", p.Name()). + Any("store", store). + Strs("args", args). + Int("arg_count", len(args)). + Msg("(pyjinja2) Run()") + + profiles, err = store.Get("profiles") + if err != nil { + return fmt.Errorf("(pyjinja2) failed to get profiles: %v", err) + } + + input, err = store.Get("file") + if err != nil { + return fmt.Errorf("(pyjinja2) failed to get input data: %v", err) + } + + // get mappings from shared data (optional) + shared, err := store.Get("shared") + if err != nil { + log.Warn().Err(err).Msg("(pyjinja2) could not retrieve shared data") + } else { + err = json.Unmarshal(shared.([]byte), &mappings) + if err != nil { + return fmt.Errorf("(pyjinja2) failed to unmarshal mappings from shared data: %v", err) + } + } + + var ps = make(map[string]any) + for profileID, profile := range profiles.(makeshift.ProfileMap) { + ps[profileID] = map[string]any{ + "id": profile.ID, + "description": profile.Description, + "data": profile.Data, + } + } + + j2, err := jinja2.NewJinja2("pyjinja", 1, + jinja2.WithGlobal("makeshift", map[string]any{ + "profiles": ps, + "plugin": map[string]any{ + "name": p.Name(), + "version": p.Version(), + "description": p.Description(), + "metadata": p.Metadata(), + }, + }), + ) + if err != nil { + return fmt.Errorf("(pyjinja2) failed to create new Jinja 2 instance: %v", err) + } + defer j2.Close() + + output, err = j2.RenderString(string(input.([]byte))) + if err != nil { + return fmt.Errorf("(pyjinja2) failed to render template: %v", err) + } + + log.Debug().Any("mappings", mappings).Send() + + // write render templates to data store output + store.Set("out", []byte(output)) + return nil +} + +func (p *Jinja2) Cleanup() error { + // nothing to clean up + log.Debug().Str("plugin", p.Name()).Msg("(pyjinja2) Cleanup()") + return nil +} + +var Makeshift Jinja2