mirror of
https://github.com/siderolabs/omni.git
synced 2026-05-05 14:46:12 +02:00
Now inline supports all three variants: - a single inline map (backward compatibility for config patches). - a list of inline maps - raw bytes, that can also contain multiple documents. `omnictl cluster template export` command was updated to export config patches/manifests as raw bytes to ensure that multiple values are properly supported. Fixes: https://github.com/siderolabs/omni/issues/2683 Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
274 lines
5.1 KiB
Go
274 lines
5.1 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package models_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.yaml.in/yaml/v4"
|
|
|
|
"github.com/siderolabs/omni/client/pkg/template/internal/models"
|
|
)
|
|
|
|
type config struct {
|
|
Inline models.InlineContent `yaml:"inline"`
|
|
}
|
|
|
|
func TestInlineContent_UnmarshalSingleMap(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `
|
|
inline:
|
|
machine:
|
|
network:
|
|
kubespan:
|
|
enabled: true
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
raw, err := got.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
assert.Contains(t, string(raw), "kubespan:")
|
|
assert.Contains(t, string(raw), "enabled: true")
|
|
}
|
|
|
|
func TestInlineContent_UnmarshalSliceOfMaps(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `
|
|
inline:
|
|
- apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: a
|
|
- apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: b
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
raw, err := got.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
docs := splitYAMLDocs(t, raw)
|
|
|
|
assert.Len(t, docs, 2)
|
|
assert.Contains(t, docs[0], "name: a")
|
|
assert.Contains(t, docs[1], "name: b")
|
|
}
|
|
|
|
func TestInlineContent_UnmarshalRawBytes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `
|
|
inline: |
|
|
machine:
|
|
network:
|
|
kubespan:
|
|
enabled: true
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
raw, err := got.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
expected := `machine:
|
|
network:
|
|
kubespan:
|
|
enabled: true
|
|
`
|
|
|
|
assert.Equal(t, expected, string(raw))
|
|
}
|
|
|
|
func TestInlineContent_UnmarshalRawBytesMultiDoc(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `inline: |
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: a
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: b
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
raw, err := got.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
assert.Contains(t, string(raw), "name: a")
|
|
assert.Contains(t, string(raw), "name: b")
|
|
assert.Contains(t, string(raw), "---")
|
|
}
|
|
|
|
func TestInlineContent_RoundtripSingleMap(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `inline:
|
|
machine:
|
|
network:
|
|
kubespan:
|
|
enabled: true
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
out, err := yaml.Marshal(got)
|
|
require.NoError(t, err)
|
|
|
|
// re-parse and compare structurally
|
|
var roundtrip config
|
|
|
|
require.NoError(t, yaml.Unmarshal(out, &roundtrip))
|
|
|
|
rawIn, err := got.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
rawOut, err := roundtrip.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, string(rawIn), string(rawOut))
|
|
}
|
|
|
|
func TestInlineContent_RoundtripSliceOfMaps(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `inline:
|
|
- apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: a
|
|
- apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: b
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
out, err := yaml.Marshal(&got)
|
|
require.NoError(t, err)
|
|
|
|
var roundtrip config
|
|
|
|
require.NoError(t, yaml.Unmarshal(out, &roundtrip))
|
|
|
|
rawIn, err := got.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
rawOut, err := roundtrip.Inline.Bytes()
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, string(rawIn), string(rawOut))
|
|
}
|
|
|
|
func TestInlineContent_RoundtripRawBytes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
src := `inline: |
|
|
machine:
|
|
network:
|
|
kubespan:
|
|
enabled: true
|
|
`
|
|
|
|
var got config
|
|
|
|
require.NoError(t, yaml.Unmarshal([]byte(src), &got))
|
|
|
|
out, err := yaml.Marshal(&got)
|
|
require.NoError(t, err)
|
|
|
|
// raw bytes are re-emitted as a literal block scalar
|
|
assert.True(t, strings.HasPrefix(string(out), "inline: |"))
|
|
assert.Contains(t, string(out), "kubespan:")
|
|
}
|
|
|
|
func TestInlineContent_OmitEmpty(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type wrapper struct {
|
|
Name string `yaml:"name"`
|
|
Inline models.InlineContent `yaml:"inline,omitempty"`
|
|
}
|
|
|
|
out, err := yaml.Marshal(wrapper{Name: "alpha"})
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "name: alpha\n", string(out))
|
|
}
|
|
|
|
func TestInlineContent_Constructors(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
mapInline := models.NewInlineContent(map[string]any{"a": 1})
|
|
|
|
mapBytes, err := mapInline.Bytes()
|
|
require.NoError(t, err)
|
|
assert.Contains(t, string(mapBytes), "a: 1")
|
|
|
|
listInline := models.NewInlineContent(map[string]any{"a": 1}, map[string]any{"b": 2})
|
|
|
|
listBytes, err := listInline.Bytes()
|
|
require.NoError(t, err)
|
|
assert.Contains(t, string(listBytes), "a: 1")
|
|
assert.Contains(t, string(listBytes), "b: 2")
|
|
|
|
rawInline := models.NewInlineContentBytes([]byte("a: 1\n"))
|
|
|
|
rawBytes, err := rawInline.Bytes()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "a: 1\n", string(rawBytes))
|
|
}
|
|
|
|
func splitYAMLDocs(t *testing.T, raw []byte) []string {
|
|
t.Helper()
|
|
|
|
dec := yaml.NewDecoder(strings.NewReader(string(raw)))
|
|
|
|
var docs []string
|
|
|
|
for {
|
|
var node yaml.Node
|
|
|
|
err := dec.Decode(&node)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
out, marshalErr := yaml.Marshal(&node)
|
|
require.NoError(t, marshalErr)
|
|
|
|
docs = append(docs, string(out))
|
|
}
|
|
|
|
return docs
|
|
}
|