1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-09 17:37:12 +00:00
kyverno/pkg/clients/dclient/fake.go

143 lines
4.5 KiB
Go
Raw Normal View History

package dclient
import (
"errors"
"fmt"
"strings"
openapiv2 "github.com/google/gnostic-models/openapiv2"
Selector with mutate target (#11208) * feature: Add LabelSelector as a field of resource spec to allow fetching by labels Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Add the capability to fetch with label selector - Add the label selector as a parameter to GetResources of the engine api client and the dclient. - Use the label selector with list options in the dclient. - convert a metav1.LabelSelector to a labels.Selector before fetching to be able to convert it to a string to be used with ListOptions. Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Pass label selector to the GetResources method Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Return the resource selector when resolving spec Signed-off-by: aerosouund <aerosound161@gmail.com> * fix: Instantiate the fake client schema using the passed gvrToListKind map and by inferring schema from passed resources All tests that use List will fail because the fake client doesn't infer the schema from the passed resources. gvrToListKind can't be fully deprecated as some parts of kyverno use the fake client without passing resources to it (resource generation). And so both approaches have to be supported. References: - https://github.com/kubernetes/client-go/issues/983 - https://github.com/kubernetes/client-go/commit/46c1ad3baa101ce5886a69f7c6a47d7777db3e56 Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add labelSelector unit test to mutate existing test. - Remove the unwanted call to GetResource. - Pass an empty map of GVR to string to the fake client constructor. Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add chainsaw test Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate helm CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * refactor: Put the LabelSelector in a separate struct Many types use the ResourceSpec struct and not all of them support label selectors. This removes the field into a separate schema dedicated to target selection called TargetSelector. It has the ResourceSpec and the selector. Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen after modifying selector comment Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> --------- Signed-off-by: aerosouund <aerosound161@gmail.com> Co-authored-by: shuting <shuting@nirmata.com>
2024-10-16 14:17:08 +03:00
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Selector with mutate target (#11208) * feature: Add LabelSelector as a field of resource spec to allow fetching by labels Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Add the capability to fetch with label selector - Add the label selector as a parameter to GetResources of the engine api client and the dclient. - Use the label selector with list options in the dclient. - convert a metav1.LabelSelector to a labels.Selector before fetching to be able to convert it to a string to be used with ListOptions. Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Pass label selector to the GetResources method Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Return the resource selector when resolving spec Signed-off-by: aerosouund <aerosound161@gmail.com> * fix: Instantiate the fake client schema using the passed gvrToListKind map and by inferring schema from passed resources All tests that use List will fail because the fake client doesn't infer the schema from the passed resources. gvrToListKind can't be fully deprecated as some parts of kyverno use the fake client without passing resources to it (resource generation). And so both approaches have to be supported. References: - https://github.com/kubernetes/client-go/issues/983 - https://github.com/kubernetes/client-go/commit/46c1ad3baa101ce5886a69f7c6a47d7777db3e56 Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add labelSelector unit test to mutate existing test. - Remove the unwanted call to GetResource. - Pass an empty map of GVR to string to the fake client constructor. Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add chainsaw test Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate helm CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * refactor: Put the LabelSelector in a separate struct Many types use the ResourceSpec struct and not all of them support label selectors. This removes the field into a separate schema dedicated to target selection called TargetSelector. It has the ResourceSpec and the selector. Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen after modifying selector comment Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> --------- Signed-off-by: aerosouund <aerosound161@gmail.com> Co-authored-by: shuting <shuting@nirmata.com>
2024-10-16 14:17:08 +03:00
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic/fake"
kubefake "k8s.io/client-go/kubernetes/fake"
)
// NewFakeClient ---testing utilities
func NewFakeClient(scheme *runtime.Scheme, gvrToListKind map[schema.GroupVersionResource]string, objects ...runtime.Object) (Interface, error) {
Selector with mutate target (#11208) * feature: Add LabelSelector as a field of resource spec to allow fetching by labels Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Add the capability to fetch with label selector - Add the label selector as a parameter to GetResources of the engine api client and the dclient. - Use the label selector with list options in the dclient. - convert a metav1.LabelSelector to a labels.Selector before fetching to be able to convert it to a string to be used with ListOptions. Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Pass label selector to the GetResources method Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Return the resource selector when resolving spec Signed-off-by: aerosouund <aerosound161@gmail.com> * fix: Instantiate the fake client schema using the passed gvrToListKind map and by inferring schema from passed resources All tests that use List will fail because the fake client doesn't infer the schema from the passed resources. gvrToListKind can't be fully deprecated as some parts of kyverno use the fake client without passing resources to it (resource generation). And so both approaches have to be supported. References: - https://github.com/kubernetes/client-go/issues/983 - https://github.com/kubernetes/client-go/commit/46c1ad3baa101ce5886a69f7c6a47d7777db3e56 Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add labelSelector unit test to mutate existing test. - Remove the unwanted call to GetResource. - Pass an empty map of GVR to string to the fake client constructor. Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add chainsaw test Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate helm CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * refactor: Put the LabelSelector in a separate struct Many types use the ResourceSpec struct and not all of them support label selectors. This removes the field into a separate schema dedicated to target selection called TargetSelector. It has the ResourceSpec and the selector. Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen after modifying selector comment Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> --------- Signed-off-by: aerosouund <aerosound161@gmail.com> Co-authored-by: shuting <shuting@nirmata.com>
2024-10-16 14:17:08 +03:00
unstructuredScheme := runtime.NewScheme()
for gvk := range scheme.AllKnownTypes() {
if unstructuredScheme.Recognizes(gvk) {
continue
}
if strings.HasSuffix(gvk.Kind, "List") {
unstructuredScheme.AddKnownTypeWithName(gvk, &unstructured.UnstructuredList{})
continue
}
unstructuredScheme.AddKnownTypeWithName(gvk, &unstructured.Unstructured{})
}
objects, err := convertObjectsToUnstructured(objects)
if err != nil {
panic(err)
}
for _, obj := range objects {
gvk := obj.GetObjectKind().GroupVersionKind()
if !unstructuredScheme.Recognizes(gvk) {
unstructuredScheme.AddKnownTypeWithName(gvk, &unstructured.Unstructured{})
}
gvk.Kind += "List"
if !unstructuredScheme.Recognizes(gvk) {
unstructuredScheme.AddKnownTypeWithName(gvk, &unstructured.UnstructuredList{})
}
}
c := fake.NewSimpleDynamicClientWithCustomListKinds(unstructuredScheme, gvrToListKind, objects...)
// the typed and dynamic client are initialized with similar resources
kclient := kubefake.NewSimpleClientset(objects...)
return &client{
dyn: c,
kube: kclient,
}, nil
}
func NewEmptyFakeClient() Interface {
gvrToListKind := map[schema.GroupVersionResource]string{}
objects := []runtime.Object{}
scheme := runtime.NewScheme()
kclient := kubefake.NewSimpleClientset(objects...)
return &client{
dyn: fake.NewSimpleDynamicClientWithCustomListKinds(scheme, gvrToListKind, objects...),
disco: NewFakeDiscoveryClient(nil),
kube: kclient,
}
}
// NewFakeDiscoveryClient returns a fakediscovery client
func NewFakeDiscoveryClient(registeredResources []schema.GroupVersionResource) *fakeDiscoveryClient {
// Load some-preregistered resources
res := []schema.GroupVersionResource{
{Version: "v1", Resource: "configmaps"},
{Version: "v1", Resource: "endpoints"},
{Version: "v1", Resource: "namespaces"},
{Version: "v1", Resource: "resourcequotas"},
{Version: "v1", Resource: "secrets"},
{Version: "v1", Resource: "serviceaccounts"},
{Group: "apps", Version: "v1", Resource: "daemonsets"},
{Group: "apps", Version: "v1", Resource: "deployments"},
{Group: "apps", Version: "v1", Resource: "statefulsets"},
}
registeredResources = append(registeredResources, res...)
return &fakeDiscoveryClient{registeredResources: registeredResources}
}
type fakeDiscoveryClient struct {
registeredResources []schema.GroupVersionResource
}
func (c *fakeDiscoveryClient) getGVR(resource string) (schema.GroupVersionResource, error) {
for _, gvr := range c.registeredResources {
if gvr.Resource == resource {
return gvr, nil
}
}
return schema.GroupVersionResource{}, errors.New("not found")
}
func (c *fakeDiscoveryClient) GetGVKFromGVR(schema.GroupVersionResource) (schema.GroupVersionKind, error) {
return schema.GroupVersionKind{}, nil
}
func (c *fakeDiscoveryClient) GetGVRFromGVK(gvk schema.GroupVersionKind) (schema.GroupVersionResource, error) {
resource := strings.ToLower(gvk.Kind) + "s"
return c.getGVR(resource)
}
func (c *fakeDiscoveryClient) FindResources(group, version, kind, subresource string) (map[TopLevelApiDescription]metav1.APIResource, error) {
r := strings.ToLower(kind) + "s"
for _, resource := range c.registeredResources {
if resource.Resource == r {
return map[TopLevelApiDescription]metav1.APIResource{
{
GroupVersion: schema.GroupVersion{Group: resource.Group, Version: resource.Version},
Kind: kind,
Resource: r,
SubResource: subresource,
}: {},
}, nil
}
}
return nil, fmt.Errorf("not found")
}
func (c *fakeDiscoveryClient) OpenAPISchema() (*openapiv2.Document, error) {
return nil, nil
}
func (c *fakeDiscoveryClient) CachedDiscoveryInterface() discovery.CachedDiscoveryInterface {
return nil
}
Selector with mutate target (#11208) * feature: Add LabelSelector as a field of resource spec to allow fetching by labels Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Add the capability to fetch with label selector - Add the label selector as a parameter to GetResources of the engine api client and the dclient. - Use the label selector with list options in the dclient. - convert a metav1.LabelSelector to a labels.Selector before fetching to be able to convert it to a string to be used with ListOptions. Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Pass label selector to the GetResources method Signed-off-by: aerosouund <aerosound161@gmail.com> * feat: Return the resource selector when resolving spec Signed-off-by: aerosouund <aerosound161@gmail.com> * fix: Instantiate the fake client schema using the passed gvrToListKind map and by inferring schema from passed resources All tests that use List will fail because the fake client doesn't infer the schema from the passed resources. gvrToListKind can't be fully deprecated as some parts of kyverno use the fake client without passing resources to it (resource generation). And so both approaches have to be supported. References: - https://github.com/kubernetes/client-go/issues/983 - https://github.com/kubernetes/client-go/commit/46c1ad3baa101ce5886a69f7c6a47d7777db3e56 Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add labelSelector unit test to mutate existing test. - Remove the unwanted call to GetResource. - Pass an empty map of GVR to string to the fake client constructor. Signed-off-by: aerosouund <aerosound161@gmail.com> * test: Add chainsaw test Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Generate helm CRDs Signed-off-by: aerosouund <aerosound161@gmail.com> * refactor: Put the LabelSelector in a separate struct Many types use the ResourceSpec struct and not all of them support label selectors. This removes the field into a separate schema dedicated to target selection called TargetSelector. It has the ResourceSpec and the selector. Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen after modifying selector comment Signed-off-by: aerosouund <aerosound161@gmail.com> * chore: Run codegen Signed-off-by: aerosouund <aerosound161@gmail.com> --------- Signed-off-by: aerosouund <aerosound161@gmail.com> Co-authored-by: shuting <shuting@nirmata.com>
2024-10-16 14:17:08 +03:00
func convertObjectsToUnstructured(objs []runtime.Object) ([]runtime.Object, error) {
ul := make([]runtime.Object, 0, len(objs))
for _, obj := range objs {
u, err := kubeutils.ObjToUnstructured(obj)
if err != nil {
return nil, err
}
ul = append(ul, u)
}
return ul, nil
}