mirror of
https://github.com/kairos-io/kairos-sdk.git
synced 2025-04-27 19:15:23 +00:00
* Fix parsing cmdline when keys have a dash If a key has a dash we need to add quotes to it before parsing it with gojq, otherwise it will fail AND the full cmdline will not be parsed! Signed-off-by: Itxaka <itxaka@kairos.io> * Actualizar bootcmdline_test.go --------- Signed-off-by: Itxaka <itxaka@kairos.io>
153 lines
3.1 KiB
Go
153 lines
3.1 KiB
Go
package unstructured
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/hashicorp/go-multierror"
|
|
"github.com/itchyny/gojq"
|
|
"gopkg.in/yaml.v3"
|
|
"strings"
|
|
)
|
|
|
|
func YAMLHasKey(query string, content []byte) (bool, error) {
|
|
data := map[string]interface{}{}
|
|
|
|
err := yaml.Unmarshal([]byte(content), &data)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
c, err := gojq.Parse(fmt.Sprintf(".%s | ..", query))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
code, err := gojq.Compile(c)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
iter := code.Run(data)
|
|
|
|
v, _ := iter.Next()
|
|
|
|
if err, ok := v.(error); ok {
|
|
return false, err
|
|
}
|
|
if v == nil {
|
|
return false, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func lookupKey(command string, data map[string]interface{}) (interface{}, error) {
|
|
query, err := gojq.Parse(command)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
code, err := gojq.Compile(query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
iter := code.Run(data)
|
|
|
|
v, ok := iter.Next()
|
|
if !ok {
|
|
return nil, errors.New("failed getting result from gojq")
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func LookupString(command string, data map[string]interface{}) (string, error) {
|
|
v, err := lookupKey(command, data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if t, ok := v.(string); ok {
|
|
return t, nil
|
|
}
|
|
|
|
return "", fmt.Errorf("value is not a string: %T", v)
|
|
}
|
|
|
|
func ReplaceValue(command string, data map[string]interface{}) (string, error) {
|
|
v, err := lookupKey(command, data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if _, ok := v.(map[string]interface{}); ok {
|
|
b, err := yaml.Marshal(v)
|
|
return string(b), err
|
|
}
|
|
|
|
return "", fmt.Errorf("unexpected type: %T", v)
|
|
}
|
|
|
|
// func ReplaceKeyValue(command string, data interface{}) (string, error) {
|
|
// LookupString(commd
|
|
// }
|
|
|
|
func jq(command string, data map[string]interface{}) (map[string]interface{}, error) {
|
|
v, err := lookupKey(command, data)
|
|
if err != nil {
|
|
return make(map[string]interface{}), err
|
|
}
|
|
|
|
if err, ok := v.(error); ok {
|
|
return nil, err
|
|
}
|
|
if t, ok := v.(map[string]interface{}); ok {
|
|
return t, nil
|
|
}
|
|
|
|
return make(map[string]interface{}), nil
|
|
}
|
|
|
|
func ToYAML(v map[string]interface{}) ([]byte, error) {
|
|
data := map[string]interface{}{}
|
|
var errs error
|
|
|
|
for k, value := range v {
|
|
prefix := "."
|
|
equal := "="
|
|
tmplKey := "%s"
|
|
tmplValue := "\"%s\""
|
|
|
|
// If key has a dash we need to add quotes to it to avoid failure parsing ut
|
|
if strings.Contains(k, "-") {
|
|
tmplKey = "\"%s\""
|
|
}
|
|
|
|
// support boolean types
|
|
if value == "true" || value == "false" {
|
|
tmplValue = "%s"
|
|
}
|
|
finalTemplate := prefix + tmplKey + equal + tmplValue
|
|
newData, err := jq(fmt.Sprintf(finalTemplate, k, value), data)
|
|
if err != nil {
|
|
errs = multierror.Append(errs, err)
|
|
continue
|
|
}
|
|
data = newData
|
|
}
|
|
|
|
out, err := yaml.Marshal(&data)
|
|
if err != nil {
|
|
errs = multierror.Append(errs, err)
|
|
}
|
|
return out, errs
|
|
}
|
|
|
|
// ToYAMLMap turns a map string interface which describes a yaml file in 'dot.yaml' format to a fully deep marshalled yaml.
|
|
func ToYAMLMap(v map[string]interface{}) (map[string]interface{}, error) {
|
|
result := map[string]interface{}{}
|
|
tempData, err := ToYAML(v)
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
err = yaml.Unmarshal(tempData, &result)
|
|
|
|
return result, err
|
|
}
|