mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-04-27 11:21:44 +00:00
Add command to render a Go template with config and state as data context
Signed-off-by: Denis Luchkin-Zhou <wyvernzora@gmail.com>
This commit is contained in:
parent
01e0a0048c
commit
234bb4b36e
36
main.go
36
main.go
@ -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: `
|
||||
|
60
pkg/action/render_template.go
Normal file
60
pkg/action/render_template.go
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright © 2022 SUSE LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
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))
|
||||
}
|
38
pkg/action/render_template_test.go
Normal file
38
pkg/action/render_template_test.go
Normal 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
2
tests/fixtures/template/test.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
configTest: "{{.Config.testKey | upper}}"
|
||||
stateTest: "{{.State.uuid | trunc 8}}"
|
Loading…
Reference in New Issue
Block a user