diff --git a/cmd/cli/kubectl-kyverno/resource/load.go b/cmd/cli/kubectl-kyverno/resource/load.go new file mode 100644 index 0000000000..37fa92a79f --- /dev/null +++ b/cmd/cli/kubectl-kyverno/resource/load.go @@ -0,0 +1,36 @@ +package resource + +import ( + "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource/convert" + "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource/loader" + yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func Load[T any](l loader.Loader, content []byte) (*T, error) { + untyped, err := l.Load(content) + if err != nil { + return nil, err + } + result, err := convert.To[T](untyped) + if err != nil { + return nil, err + } + return result, nil +} + +func LoadResources(l loader.Loader, content []byte) ([]unstructured.Unstructured, error) { + documents, err := yamlutils.SplitDocuments(content) + if err != nil { + return nil, err + } + var resources []unstructured.Unstructured + for _, document := range documents { + untyped, err := l.Load(document) + if err != nil { + return nil, err + } + resources = append(resources, untyped) + } + return resources, nil +} diff --git a/cmd/cli/kubectl-kyverno/resource/load_test.go b/cmd/cli/kubectl-kyverno/resource/load_test.go new file mode 100644 index 0000000000..2182373944 --- /dev/null +++ b/cmd/cli/kubectl-kyverno/resource/load_test.go @@ -0,0 +1,107 @@ +package resource + +import ( + "testing" + + "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource/loader" + "sigs.k8s.io/kubectl-validate/pkg/openapiclient" +) + +const ( + singleResource string = `apiVersion: v1 +kind: Namespace +metadata: + name: prod-bus-app1 + labels: + purpose: production` + + multipleResources string = ` +apiVersion: v1 +kind: Pod +metadata: + labels: + run: nginx + name: nginx + namespace: default +spec: + containers: + - image: nginx + name: nginx + resources: {} +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: redis + name: redis + namespace: default +spec: + containers: + - image: redis + name: redis + resources: {}` + + resourceWithComment string = ` +### POD ### +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: nginx + name: nginx + namespace: default +spec: + containers: + - image: nginx + name: nginx + resources: {}` +) + +func Test_LoadResources(t *testing.T) { + l, err := loader.New(openapiclient.NewHardcodedBuiltins("1.27")) + if err != nil { + t.Fatal(err) + } + tests := []struct { + name string + resources string + wantLoaded int + wantErr bool + }{ + { + name: "load no resource with empy string", + resources: "", + wantLoaded: 0, + wantErr: false, + }, + { + name: "load single resource", + resources: singleResource, + wantLoaded: 1, + wantErr: false, + }, + { + name: "load multiple resources", + resources: multipleResources, + wantLoaded: 2, + wantErr: false, + }, + { + name: "load resource with comment", + resources: resourceWithComment, + wantLoaded: 1, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if res, err := LoadResources(l, []byte(tt.resources)); (err != nil) != tt.wantErr { + t.Errorf("loader.Resources() error = %v, wantErr %v", err, tt.wantErr) + } else if len(res) != tt.wantLoaded { + t.Errorf("loader.Resources() loaded amount = %v, wantLoaded %v", len(res), tt.wantLoaded) + } + }) + } +}