From e8e92b068fb0b8e6e1147a63e6263070c133c90d Mon Sep 17 00:00:00 2001 From: Shubham Gupta Date: Fri, 13 Oct 2023 20:02:10 +0530 Subject: [PATCH] raised assert Signed-off-by: Shubham Gupta --- pkg/client/assert.go | 38 ++++++++++++++++++++++++++++++ pkg/client/client.go | 2 ++ pkg/runner/runner.go | 31 +++++++++++++++++++++--- pkg/utils/kubernetes/kubernetes.go | 14 +++++++++++ pkg/utils/kubernetes/subset.go | 5 ++++ 5 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 pkg/client/assert.go create mode 100644 pkg/utils/kubernetes/kubernetes.go create mode 100644 pkg/utils/kubernetes/subset.go diff --git a/pkg/client/assert.go b/pkg/client/assert.go new file mode 100644 index 000000000..d5562b398 --- /dev/null +++ b/pkg/client/assert.go @@ -0,0 +1,38 @@ +package client + +import ( + "context" + + "github.com/kyverno/chainsaw/pkg/utils/kubernetes" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +func Assert(ctx context.Context, client Client, expected ctrlclient.Object, namespace string) (bool, error) { + + // Step 1: Get the object from the cluster + // Step 2 We need to make sure that obj is cluster scoped or namespaced + // Step 3: Compare the object with the expected object + // Step 4: Return true if the objects are equal, false otherwise + + // Try to check if the object is namespaced or cluster scoped and get the name and namespace + name, ns, err := kubernetes.Namespaced(expected, namespace) + if err != nil { + return false, err + } + + gvk := expected.GetObjectKind().GroupVersionKind() + + actualObj := unstructured.Unstructured{} + + err = client.Get(ctx, ctrlclient.ObjectKey{Name: name, Namespace: ns}, &actualObj) + if err != nil { + return false, err + } + + expectedObj, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(expected) + + kubernetes.IsSubset(actualObj, expectedObj) + return true, nil +} diff --git a/pkg/client/client.go b/pkg/client/client.go index f9e1a6a75..592733ee7 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -1,6 +1,7 @@ package client import ( + "k8s.io/apimachinery/pkg/runtime" _ "k8s.io/client-go/plugin/pkg/client/auth" // package needed for auth providers like GCP "k8s.io/client-go/rest" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -9,6 +10,7 @@ import ( type Client interface { ctrlclient.Reader ctrlclient.Writer + IsObjectNamespaced(obj runtime.Object) (bool, error) } func New(cfg *rest.Config) (Client, error) { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 54082f3dc..7c8991b76 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -73,12 +73,12 @@ func runTest(t *testing.T, cfg *rest.Config, test discovery.Test) { step := test.Spec.Steps[i] t.Run(fmt.Sprintf("step-%d", i+1), func(t *testing.T) { t.Helper() - executeStep(t, test.BasePath, step, c) + executeStep(t, test.BasePath, step, c, "") }) } } -func executeStep(t *testing.T, basePath string, step v1alpha1.TestStepSpec, c client.Client) { +func executeStep(t *testing.T, basePath string, namespace string, step v1alpha1.TestStepSpec, c client.Client) { t.Helper() for _, apply := range step.Apply { resources, err := resource.Load(filepath.Join(basePath, apply.File)) @@ -86,10 +86,35 @@ func executeStep(t *testing.T, basePath string, step v1alpha1.TestStepSpec, c cl t.Fatal(err) } for i := range resources { - _, err := client.CreateOrUpdate(context.Background(), c, &resources[i]) + resource := &resources[i] + if resource.GetNamespace() == "" { + namespaced, err := c.IsObjectNamespaced(resource) + if err != nil { + t.Fatal(err) + } + if namespaced { + resource.SetNamespace(namespace) + } + } + _, err := client.CreateOrUpdate(context.Background(), c, resource) if err != nil { t.Fatal(err) } } } + + for _, assert := range step.Assert { + resources, err := resource.Load(assert.File) + if err != nil { + t.Fatal(err) + } + + for i := range resources { + _, err := client.Assert(context.Background(), c, &resources[i]) + if err != nil { + t.Fatal(err) + } + } + + } } diff --git a/pkg/utils/kubernetes/kubernetes.go b/pkg/utils/kubernetes/kubernetes.go new file mode 100644 index 000000000..f57a6c640 --- /dev/null +++ b/pkg/utils/kubernetes/kubernetes.go @@ -0,0 +1,14 @@ +package kubernetes + +import ( + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// This determine if the resource is clustered or namespaced +// if the resource is namespaced and doesn't have a namespace set, use the pet namespace +// if the resource is namespaced and has a namespace set, use the namespace set +// return namespace, name, error +func Namespaced(obj ctrlclient.Object, petNamespace string) (string, string, error) { + + return "", "", nil +} diff --git a/pkg/utils/kubernetes/subset.go b/pkg/utils/kubernetes/subset.go new file mode 100644 index 000000000..93b3c5a7f --- /dev/null +++ b/pkg/utils/kubernetes/subset.go @@ -0,0 +1,5 @@ +package kubernetes + +func IsSubset(actual, expected interface{}) bool { + return false +}