From 3f57bab7c4daca49721b26e7f7002c8e3833142e Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Mon, 30 Sep 2024 15:02:46 +0200 Subject: [PATCH] fix(manifests): split YAML using reader Signed-off-by: Hidde Beydals --- internal/manifests/manifests.go | 21 +++++++++++---- internal/manifests/manifests_test.go | 38 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/internal/manifests/manifests.go b/internal/manifests/manifests.go index 03d550b..b7c1464 100644 --- a/internal/manifests/manifests.go +++ b/internal/manifests/manifests.go @@ -1,12 +1,15 @@ package manifests import ( + "bufio" "bytes" "errors" "fmt" + "io" "strings" - "sigs.k8s.io/yaml" + "k8s.io/apimachinery/pkg/util/yaml" + libyaml "sigs.k8s.io/yaml" ) func JSONStringsToYAMLBytes(jsonManifests []string) ([][]byte, error) { @@ -15,7 +18,7 @@ func JSONStringsToYAMLBytes(jsonManifests []string) ([][]byte, error) { for i, jsonManifest := range jsonManifests { var err error if yamlManifests[i], err = - yaml.JSONToYAML([]byte(jsonManifest)); err != nil { + libyaml.JSONToYAML([]byte(jsonManifest)); err != nil { return nil, fmt.Errorf("error converting JSON manifest to YAML: %w", err) } @@ -28,16 +31,24 @@ func CombineYAML(manifests [][]byte) []byte { } func SplitYAML(manifest []byte) (map[string][]byte, error) { - manifests := bytes.Split(manifest, []byte("---\n")) + dec := yaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(manifest))) manifestsByResourceTypeAndName := map[string][]byte{} - for _, manifest = range manifests { + for { + manifest, err := dec.Read() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + return nil, fmt.Errorf("error reading YAML document: %w", err) + } + resource := struct { Kind string `json:"kind"` Metadata struct { Name string `json:"name"` } `json:"metadata"` }{} - if err := yaml.Unmarshal(manifest, &resource); err != nil { + if err := libyaml.Unmarshal(manifest, &resource); err != nil { return nil, fmt.Errorf("error unmarshaling resource: %w", err) } if resource.Kind == "" { diff --git a/internal/manifests/manifests_test.go b/internal/manifests/manifests_test.go index b3f6447..2b92d1c 100644 --- a/internal/manifests/manifests_test.go +++ b/internal/manifests/manifests_test.go @@ -84,6 +84,44 @@ func TestSplitYAML(t *testing.T) { require.Equal(t, "resource is missing metadata.name field", err.Error()) }, }, + { + name: "YAML containing separators within the spec", + manifests: []byte(`apiVersion: v1 +data: + mappings.yml: |- + # Licensed to the Apache Software Foundation (ASF) under one + # or more contributor license agreements. See the NOTICE file + # distributed with this work for additional information + # regarding copyright ownership. The ASF licenses this file + # to you 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. + --- + mappings: + some: mappings +kind: ConfigMap +metadata: + labels: + chart: airflow-1.11.0 + component: config + heritage: Helm + release: airflow + tier: airflow + name: airflow-statsd`), + assertions: func(t *testing.T, manifests map[string][]byte, err error) { + require.NoError(t, err) + require.Len(t, manifests, 1) + }, + }, { name: "success", manifests: []byte(`kind: foo