diff --git a/api/resource/factory.go b/api/resource/factory.go index fb01bc8ceec..c4d7b45d4df 100644 --- a/api/resource/factory.go +++ b/api/resource/factory.go @@ -143,7 +143,7 @@ func (rf *Factory) resourcesFromRNodes( return } -func (rf *Factory) RNodesFromBytes(b []byte) (result []*yaml.RNode, err error) { +func (rf *Factory) RNodesFromBytes(b []byte) ([]*yaml.RNode, error) { nodes, err := kio.FromBytes(b) if err != nil { return nil, err @@ -152,9 +152,25 @@ func (rf *Factory) RNodesFromBytes(b []byte) (result []*yaml.RNode, err error) { if err != nil { return nil, err } + // Replace YAML anchors before converting any FooList nodes into []Foo. + // Anchors work across elements of a FooList because it's still one node, + // but won't work across those elements after their expansion. + for _, n := range nodes { + if err = n.DeAnchor(); err != nil { + return nil, err + } + } + return rf.inlineAnyEmbeddedLists(nodes) +} + +// inlineAnyEmbeddedLists scans the RNode slice for nodes named FooList. +// Such nodes are expected to be lists of RNodes, each of type Foo. +// These lists are replaced in the result by their inlined content. +func (rf *Factory) inlineAnyEmbeddedLists( + nodes []*yaml.RNode) (result []*yaml.RNode, err error) { + var n0 *yaml.RNode for len(nodes) > 0 { - n0 := nodes[0] - nodes = nodes[1:] + n0, nodes = nodes[0], nodes[1:] kind := n0.GetKind() if !strings.HasSuffix(kind, "List") { result = append(result, n0) @@ -164,7 +180,7 @@ func (rf *Factory) RNodesFromBytes(b []byte) (result []*yaml.RNode, err error) { var m map[string]interface{} m, err = n0.Map() if err != nil { - return nil, err + return nil, fmt.Errorf("trouble expanding list of %s; %w", kind, err) } items, ok := m["items"] if !ok { diff --git a/api/resource/factory_test.go b/api/resource/factory_test.go index 905b8620282..f03cba8f46f 100644 --- a/api/resource/factory_test.go +++ b/api/resource/factory_test.go @@ -639,17 +639,14 @@ data: feeling: *color-used `), exp: expected{ - // TODO(#3675) : the anchor should be replaced. - // Anchors are replaced in the List above due to a different code path - // (when the list is inlined). out: []string{` apiVersion: v1 kind: ConfigMap metadata: name: wildcard data: - color: &color-used blue - feeling: *color-used + color: blue + feeling: blue `}, }, },