func Marshal(objs ...interface{}) ([]byte, error) {
	var buf bytes.Buffer
	fw := serializer.NewYAMLFrameWriter(&buf)
	data := [][]byte{}
	for _, obj := range objs {
		value, err := k8syaml.Marshal(obj)
		if err != nil {
			return nil, err
		}
		data = append(data, value)
	}
	if err := serializer.WriteFrameList(fw, data); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
Marshal takes one or more struts and uses sig.k8s.io/yaml to
convert into a string.  The conversion adheres to the json
comments in the struct
package manifest
import (
	"bytes"
	"io"
	"github.com/weaveworks/libgitops/pkg/serializer"
	kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
	k8syaml "sigs.k8s.io/yaml"
)
const (
	corev1Version    = "v1"
	listKind         = "List"
	namespaceKind    = "Namespace"
	podKind          = "Pod"
	DefaultNamespace = "weavek8sops"
)
var DefaultAddonNamespaces = map[string]string{"weave-net": "kube-system"}
func WithNamespace(rc io.ReadCloser, namespace string) ([]byte, error) {
	fr := serializer.NewYAMLFrameReader(rc)
	buf := new(bytes.Buffer)
	fw := serializer.NewYAMLFrameWriter(buf)
	frames, err := serializer.ReadFrameList(fr)
	if err != nil {
		return nil, err
	}
	if namespace == "" {
		if err := serializer.WriteFrameList(fw, frames); err != nil {
			return nil, err
		}
		return buf.Bytes(), nil
	}
	for _, frame := range frames {
		obj, err := kyaml.Parse(string(frame))
		if err != nil {
			return nil, err
		}
		meta, err := obj.GetMeta()
		if err != nil {
			return nil, err
		}
		if meta.APIVersion == corev1Version && meta.Kind == listKind {
			if err := visitElementsForPath(obj, func(item *kyaml.RNode) error {
				return setNamespaceOnObject(item, namespace)
			}, "items"); err != nil {
				return nil, err
			}
		} else {
			if err := setNamespaceOnObject(obj, namespace); err != nil {
				return nil, err
			}
		}
		str, err := obj.String()
		if err != nil {
			return nil, err
		}
		if _, err := fw.Write([]byte(str)); err != nil {
			return nil, err
		}
	}
	return buf.Bytes(), nil
}
func WithImageTagUpdate(rc io.ReadCloser, updater func(string) (string, error)) ([]byte, error) {
	fr := serializer.NewYAMLFrameReader(rc)
	buf := new(bytes.Buffer)
	fw := serializer.NewYAMLFrameWriter(buf)
	frames, err := serializer.ReadFrameList(fr)
	if err != nil {
		return nil, err
	}
	for _, frame := range frames {
		obj, err := kyaml.Parse(string(frame))
		if err != nil {
			return nil, err
		}
		if err := processImageSuffixEntry(obj, updater); err != nil {
			return nil, err
		}
		str, err := obj.String()
		if err != nil {
			return nil, err
		}
		if _, err := fw.Write([]byte(str)); err != nil {
			return nil, err
		}
	}
	return buf.Bytes(), nil
}
func processImageSuffixEntry(obj *kyaml.RNode, updater func(string) (string, error)) error {
	meta, err := obj.GetMeta()
	if err != nil {
		return err
	}
	if meta.APIVersion == corev1Version && meta.Kind == listKind {
		if err := visitElementsForPath(obj, func(item *kyaml.RNode) error {
			return processImageSuffixEntry(item, updater)
		}, "items"); err != nil {
			return err
		}
	} else {
		updated, err := updateImage(obj, kyaml.Lookup("spec", "template", "spec", "containers"), updater)
		if err != nil {
			return err
		}
		if !updated {
			meta, err := obj.GetMeta()
			if err != nil {
				return err
			}
			if meta.APIVersion == corev1Version && meta.Kind == podKind {
				if _, err := updateImage(obj, kyaml.Lookup("spec", "containers"), updater); err != nil {
					return err
				}
			}
		}
	}
	return nil
}
func updateImage(obj *kyaml.RNode, lookup kyaml.PathGetter, updater func(string) (string, error)) (bool, error) {
	node, err := obj.Pipe(lookup)
	if err != nil {
		return false, err
	}
	elems, err := node.Elements()
	if err != nil {
		return false, err
	}
	for _, container := range elems {
		existingTag, err := container.Pipe(kyaml.Get("image"))
		if err != nil {
			return false, err
		}
		updated, err := updater(existingTag.YNode().Value)
		if err != nil {
			return false, err
		}
		container.Pipe(kyaml.SetField("image", kyaml.NewScalarRNode(updated)))
		return true, nil
	}
	return false, nil
}
func setNamespaceOnObject(obj *kyaml.RNode, namespace string) error {
	meta, err := obj.GetMeta()
	if err != nil {
		return err
	}
	namespaceFilter := setNamespaceFilter(namespace)
	if meta.APIVersion == corev1Version && meta.Kind == namespaceKind {
		namespaceFilter = kyaml.SetField("name", kyaml.NewScalarRNode(namespace))
	}
	err = obj.PipeE(
		kyaml.LookupCreate(kyaml.MappingNode, "metadata"),
		namespaceFilter,
	)
	if err != nil {
		return err
	}
	return visitElementsForPath(obj, func(node *kyaml.RNode) error {
		return node.PipeE(setNamespaceFilter(namespace))
	}, "subjects")
}
func visitElementsForPath(obj *kyaml.RNode, fn func(node *kyaml.RNode) error, paths ...string) error {
	list, err := obj.Pipe(kyaml.Lookup(paths...))
	if err != nil {
		return err
	}
	return list.VisitElements(fn)
}
func setNamespaceFilter(ns string) kyaml.FieldSetter {
	return kyaml.SetField("namespace", kyaml.NewScalarRNode(ns))
}