fix: support 'List' type manifests

Fixes #7636

This support a `List`-type manifests by unwrapping them into individual
objects.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
Andrey Smirnov 2023-08-21 16:48:37 +04:00
parent 574d48e540
commit b56e8b7d9b
No known key found for this signature in database
GPG Key ID: FE042E3D4085A811
3 changed files with 65 additions and 1 deletions

View File

@ -13,6 +13,7 @@ import (
"github.com/siderolabs/gen/slices"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/yaml"
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
@ -32,6 +33,8 @@ type manifest struct {
}
// SetYAML parses manifest from YAML.
//
//nolint:gocyclo
func (a manifest) SetYAML(yamlBytes []byte) error {
a.Manifest.TypedSpec().Items = nil
reader := yaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(yamlBytes)))
@ -68,7 +71,23 @@ func (a manifest) SetYAML(yamlBytes []byte) error {
return fmt.Errorf("error loading JSON manifest into unstructured: %w", err)
}
a.Manifest.TypedSpec().Items = append(a.Manifest.TypedSpec().Items, k8s.SingleManifest{Object: obj.Object})
// if the manifest is a list, we will unwrap it
if obj.IsList() {
if err = obj.EachListItem(func(item runtime.Object) error {
obj, ok := item.(*unstructured.Unstructured)
if !ok {
return fmt.Errorf("list item is not Unstructured: %T", item)
}
a.Manifest.TypedSpec().Items = append(a.Manifest.TypedSpec().Items, k8s.SingleManifest{Object: obj.Object})
return nil
}); err != nil {
return fmt.Errorf("error unwrapping a List: %w", err)
}
} else {
a.Manifest.TypedSpec().Items = append(a.Manifest.TypedSpec().Items, k8s.SingleManifest{Object: obj.Object})
}
}
return nil

View File

@ -5,6 +5,7 @@
package k8s_test
import (
_ "embed"
"strings"
"testing"
@ -50,3 +51,19 @@ rules:
assert.Len(t, adapter.Objects(), 1)
assert.Equal(t, adapter.Objects()[0].GetKind(), "Policy")
}
//go:embed testdata/list.yaml
var listManifest []byte
func TestManifestSetYAMLList(t *testing.T) {
manifest := k8s.NewManifest(k8s.ControlPlaneNamespaceName, "test")
adapter := k8sadapter.Manifest(manifest)
require.NoError(t, adapter.SetYAML(listManifest))
assert.Len(t, adapter.Objects(), 2)
assert.Equal(t, "ClusterRoleBinding", adapter.Objects()[0].GetKind())
assert.Equal(t, "system:cloud-node-controller", adapter.Objects()[0].GetName())
assert.Equal(t, "ClusterRoleBinding", adapter.Objects()[1].GetKind())
assert.Equal(t, "system:cloud-controller-manager", adapter.Objects()[1].GetName())
}

View File

@ -0,0 +1,28 @@
apiVersion: v1
items:
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:cloud-node-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:cloud-node-controller
subjects:
- kind: ServiceAccount
name: cloud-node-controller
namespace: kube-system
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:cloud-controller-manager
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:cloud-controller-manager
subjects:
- kind: ServiceAccount
name: cloud-controller-manager
namespace: kube-system
kind: List
metadata: {}