Merge pull request #159 from wyvernzora/main

Add command to render a Go template
This commit is contained in:
Dimitris Karakasilis
2023-10-20 11:00:11 +03:00
committed by GitHub
4 changed files with 118 additions and 2 deletions

36
main.go
View File

@@ -5,14 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/kairos-io/kairos-agent/v2/pkg/action"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
"github.com/kairos-io/kairos-agent/v2/internal/agent"
"github.com/kairos-io/kairos-agent/v2/internal/bus"
"github.com/kairos-io/kairos-agent/v2/internal/common"
@@ -367,6 +367,38 @@ enabled: true`,
},
},
},
{
Name: "render-template",
Usage: "Render a Go template",
Description: "Render a Go template with machine state and config as data context",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Aliases: []string{"f"},
Required: true,
},
},
Action: func(c *cli.Context) error {
config, err := agentConfig.Scan(collector.Directories(configScanDir...), collector.NoLogs, collector.StrictValidation(c.Bool("strict-validation")))
if err != nil {
return err
}
runtime, err := state.NewRuntime()
if err != nil {
return err
}
result, err := action.RenderTemplate(c.String("file"), config, runtime)
if err != nil {
return err
}
_, err = os.Stdout.Write(result)
return err
},
},
{
Name: "interactive-install",
Description: `

View File

@@ -0,0 +1,44 @@
package action
import (
"bytes"
"github.com/Masterminds/sprig/v3"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-sdk/state"
"gopkg.in/yaml.v3"
"os"
"text/template"
)
func RenderTemplate(path string, config *config.Config, runtime state.Runtime) ([]byte, error) {
// Marshal runtime to YAML then to Map so that it is consistent with the output of 'kairos-agent state'
var runtimeMap map[string]interface{}
err := yaml.Unmarshal([]byte(runtime.String()), &runtimeMap)
if err != nil {
return nil, err
}
tpl, err := loadTemplateFile(path)
if err != nil {
return nil, err
}
result := new(bytes.Buffer)
err = tpl.Execute(result, map[string]interface{}{
"Config": config.Config,
"State": runtimeMap,
})
if err != nil {
return nil, err
}
return result.Bytes(), nil
}
func loadTemplateFile(path string) (*template.Template, error) {
tpl := template.New(path).Funcs(sprig.FuncMap())
content, err := os.ReadFile(path)
if err != nil {
return nil, err
}
return tpl.Parse(string(content))
}

View File

@@ -0,0 +1,38 @@
package action
import (
"fmt"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-sdk/collector"
"github.com/kairos-io/kairos-sdk/state"
"gopkg.in/yaml.v3"
"os"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("RenderTemplate action test", func() {
It("renders the template with config and state", func() {
config := agentConfig.NewConfig()
config.Config = collector.Config{
"testKey": "testValue",
}
runtime, err := state.NewRuntime()
fmt.Println(os.Getwd())
result, err := RenderTemplate("../../tests/fixtures/template/test.yaml", config, runtime)
Expect(err).ToNot(HaveOccurred())
Expect(result).ToNot(BeNil())
Expect(len(result)).ToNot(BeZero())
var data map[string]string
err = yaml.Unmarshal(result, &data)
Expect(err).ToNot(HaveOccurred())
Expect(data).To(HaveKeyWithValue("configTest", "TESTVALUE"))
Expect(data["stateTest"]).To(MatchRegexp("^[0-9a-f]{8}$"))
})
})

2
tests/fixtures/template/test.yaml vendored Normal file
View File

@@ -0,0 +1,2 @@
configTest: "{{.Config.testKey | upper}}"
stateTest: "{{.State.uuid | trunc 8}}"