Skip to content

Commit

Permalink
fix: trim leading spaces\newlines in inline manifest contents
Browse files Browse the repository at this point in the history
In route `LoadPatches` -> `configpatcher.Apply` -> `configloader.NewFromBytes` any leading newlines will be transformed  into `|4` yaml. We want to prevent that.

Closes #7993

Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
  • Loading branch information
DmitriyMV committed Dec 4, 2023
1 parent dbf274d commit eecc4db
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 5 deletions.
50 changes: 45 additions & 5 deletions pkg/machinery/config/configpatcher/apply_test.go
Expand Up @@ -2,7 +2,6 @@
// 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/.

//nolint:dupl
package configpatcher_test

import (
Expand All @@ -20,13 +19,16 @@ import (
var config []byte

//go:embed testdata/apply/expected.yaml
var expected []byte
var expected string

//go:embed testdata/multidoc/config.yaml
var configMultidoc []byte

//go:embed testdata/multidoc/expected.yaml
var expectedMultidoc []byte
var expectedMultidoc string

//go:embed testdata/apply/expected_manifests.yaml
var expectedManifests string

func TestApply(t *testing.T) {
patches, err := configpatcher.LoadPatches([]string{
Expand Down Expand Up @@ -61,7 +63,7 @@ func TestApply(t *testing.T) {
bytes, err := out.Bytes()
require.NoError(t, err)

assert.Equal(t, string(expected), string(bytes))
assert.Equal(t, expected, string(bytes))
})
}
}
Expand Down Expand Up @@ -126,7 +128,7 @@ func TestApplyMultiDoc(t *testing.T) {
bytes, err := out.Bytes()
require.NoError(t, err)

assert.Equal(t, string(expectedMultidoc), string(bytes))
assert.Equal(t, expectedMultidoc, string(bytes))
})
}
}
Expand Down Expand Up @@ -170,3 +172,41 @@ func TestApplyAuditPolicy(t *testing.T) {
})
}
}

func TestApplyWithManifestNewline(t *testing.T) {
patches, err := configpatcher.LoadPatches([]string{
"@testdata/apply/strategic4.yaml",
})
require.NoError(t, err)

cfg, err := configloader.NewFromBytes(config)
require.NoError(t, err)

for _, tt := range []struct {
name string
input configpatcher.Input
}{
{
name: "WithConfig",
input: configpatcher.WithConfig(cfg),
},
{
name: "WithBytes",
input: configpatcher.WithBytes(config),
},
} {
t.Run(tt.name, func(t *testing.T) {
out, err := configpatcher.Apply(tt.input, patches)
require.NoError(t, err)

bytes, err := out.Bytes()
require.NoError(t, err)

// Verify that after all our transformations the YAML is still valid and newline is removed
_, err = configloader.NewFromBytes(bytes)
require.NoError(t, err)

assert.Equal(t, expectedManifests, string(bytes))
})
}
}
@@ -0,0 +1,27 @@
version: v1alpha1
machine:
type: ""
token: ""
certSANs: []
network:
hostname: hostname1
interfaces:
- interface: eth0
dhcp: true
cluster:
controlPlane: null
inlineManifests:
- name: cilium
contents: |
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cilium
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cilium-operator
namespace: kube-system
17 changes: 17 additions & 0 deletions pkg/machinery/config/configpatcher/testdata/apply/strategic4.yaml
@@ -0,0 +1,17 @@
cluster:
inlineManifests:
- name: cilium
contents: | # the empty newline below is important
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cilium
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cilium-operator
namespace: kube-system
17 changes: 17 additions & 0 deletions pkg/machinery/config/types/v1alpha1/v1alpha1_types.go
Expand Up @@ -2183,6 +2183,23 @@ type VolumeMountConfig struct {
// ClusterInlineManifests is a list of ClusterInlineManifest.
type ClusterInlineManifests []ClusterInlineManifest

// UnmarshalYAML implements yaml.Unmarshaler.
func (manifests *ClusterInlineManifests) UnmarshalYAML(value *yaml.Node) error {
var result []ClusterInlineManifest

if err := value.Decode(&result); err != nil {
return err
}

for i := range result {
result[i].InlineManifestContents = strings.TrimLeft(result[i].InlineManifestContents, "\t\n\v\f\r")
}

*manifests = result

return nil
}

// ClusterInlineManifest struct describes inline bootstrap manifests for the user.
type ClusterInlineManifest struct {
// description: |
Expand Down

0 comments on commit eecc4db

Please sign in to comment.