seedling: Return configuration data from the agent (#567)

* 🌱 Return configuration data from the agent

Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>

* 🤖 Cover query by tests

Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>

Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
This commit is contained in:
Ettore Di Giacinto
2022-12-19 17:01:57 +01:00
committed by Itxaka
parent 2bf4793c41
commit a909c44620
3 changed files with 57 additions and 9 deletions

View File

@@ -10,12 +10,13 @@ import (
"unicode"
retry "github.com/avast/retry-go"
"github.com/itchyny/gojq"
"github.com/kairos-io/kairos/pkg/machine"
"github.com/kairos-io/kairos/sdk/bundles"
"github.com/kairos-io/kairos/sdk/unstructured"
yip "github.com/mudler/yip/pkg/schema"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)
type Install struct {
@@ -106,6 +107,38 @@ func (c Config) String() string {
return string(dat)
}
func (c Config) Query(s string) (res string, err error) {
s = fmt.Sprintf(".%s", s)
jsondata := map[string]interface{}{}
err = yaml.Unmarshal([]byte(c.String()), &jsondata)
if err != nil {
return
}
query, err := gojq.Parse(s)
if err != nil {
return res, err
}
iter := query.Run(jsondata) // or query.RunWithContext
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
return res, fmt.Errorf("failed parsing, error: %w", err)
}
dat, err := yaml.Marshal(v)
if err != nil {
break
}
res += string(dat)
}
return
}
func allFiles(dir []string) []string {
files := []string{}
for _, d := range dir {
@@ -122,7 +155,7 @@ func Scan(opts ...Option) (c *Config, err error) {
return nil, err
}
c = parseConfig(o.ScanDir)
c = parseConfig(o.ScanDir, o.NoLogs)
if o.MergeBootCMDLine {
d, err := machine.DotToYAML(o.BootCMDLineFile)
@@ -291,18 +324,22 @@ func FindYAMLWithKey(s string, opts ...Option) ([]string, error) {
}
// parseConfig merges all config back in one structure.
func parseConfig(dir []string) *Config {
func parseConfig(dir []string, nologs bool) *Config {
files := allFiles(dir)
c := &Config{}
for _, f := range files {
if fileSize(f) > 1.0 {
fmt.Printf("warning: skipping %s. too big (>1MB)\n", f)
if !nologs {
fmt.Printf("warning: skipping %s. too big (>1MB)\n", f)
}
continue
}
if strings.Contains(f, "userdata") || filepath.Ext(f) == ".yml" || filepath.Ext(f) == ".yaml" {
b, err := os.ReadFile(f)
if err != nil {
fmt.Printf("warning: skipping %s. %s\n", f, err.Error())
if !nologs {
fmt.Printf("warning: skipping %s. %s\n", f, err.Error())
}
continue
}
yaml.Unmarshal(b, c) //nolint:errcheck
@@ -311,7 +348,9 @@ func parseConfig(dir []string) *Config {
c.header = header
}
} else {
fmt.Printf("warning: skipping %s (extension).\n", f)
if !nologs {
fmt.Printf("warning: skipping %s (extension).\n", f)
}
}
}

View File

@@ -50,7 +50,7 @@ var _ = Describe("Config", func() {
ExpectWithOffset(1, header).To(Equal(DefaultHeader))
}
It("reads from bootargs", func() {
It("reads from bootargs and can query", func() {
err := os.WriteFile(filepath.Join(d, "b"), []byte(`zz.foo="baa" options.foo=bar`), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
@@ -58,6 +58,8 @@ var _ = Describe("Config", func() {
Expect(err).ToNot(HaveOccurred())
headerCheck(c)
Expect(c.Options["foo"]).To(Equal("bar"))
Expect(c.Query("options")).To(Equal("foo: bar\n"))
Expect(c.Query("options.foo")).To(Equal("bar\n"))
})
It("reads multiple config files", func() {
@@ -96,7 +98,7 @@ c: d
var cc string = `#kairos-config
baz: bar
kairos:
network_token: foo
network_token: foo
`
err := os.WriteFile(filepath.Join(d, "test.yaml"), []byte(cc), os.ModePerm)
@@ -114,7 +116,8 @@ fooz:
Expect(err).ToNot(HaveOccurred())
Expect(providerCfg.Kairos).ToNot(BeNil())
Expect(providerCfg.Kairos.NetworkToken).To(Equal("foo"))
Expect(c.String()).To(Equal(cc))
Expect(c.String()).To(Equal(cc), c.String(), cc)
})
It("merges with bootargs", func() {

View File

@@ -4,10 +4,16 @@ type Options struct {
ScanDir []string
BootCMDLineFile string
MergeBootCMDLine bool
NoLogs bool
}
type Option func(o *Options) error
var NoLogs Option = func(o *Options) error {
o.NoLogs = true
return nil
}
func (o *Options) Apply(opts ...Option) error {
for _, oo := range opts {
if err := oo(o); err != nil {