From 50636e3a7ed0aa6a2f9c082dd2aa64e124ba5f1b Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 5 Dec 2021 13:52:06 +0200 Subject: [PATCH] supporting list of include-namespaces --- resourcehandler/fieldselector.go | 36 ++++++++++++--------- resourcehandler/fieldselector_test.go | 28 ++++++++++++++-- resourcehandler/k8sresources.go | 46 +++++++++++++++------------ 3 files changed, 73 insertions(+), 37 deletions(-) diff --git a/resourcehandler/fieldselector.go b/resourcehandler/fieldselector.go index 56563f10..425d3d7d 100644 --- a/resourcehandler/fieldselector.go +++ b/resourcehandler/fieldselector.go @@ -9,14 +9,14 @@ import ( ) type IFieldSelector interface { - GetNamespacesSelector(*schema.GroupVersionResource) string + GetNamespacesSelectors(*schema.GroupVersionResource) []string } type EmptySelector struct { } -func (es *EmptySelector) GetNamespacesSelector(resource *schema.GroupVersionResource) string { - return "" +func (es *EmptySelector) GetNamespacesSelectors(resource *schema.GroupVersionResource) []string { + return []string{} } type ExcludeSelector struct { @@ -34,16 +34,28 @@ type IncludeSelector struct { func NewIncludeSelector(ns string) *IncludeSelector { return &IncludeSelector{namespace: ns} } -func (es *ExcludeSelector) GetNamespacesSelector(resource *schema.GroupVersionResource) string { - return getNamespacesSelector(resource, es.namespace, "!=") +func (es *ExcludeSelector) GetNamespacesSelectors(resource *schema.GroupVersionResource) []string { + fieldSelectors := "" + for _, n := range strings.Split(es.namespace, ",") { + if n != "" { + fieldSelectors += getNamespacesSelector(resource, n, "!=") + "," + } + } + return []string{fieldSelectors} + } -func (is *IncludeSelector) GetNamespacesSelector(resource *schema.GroupVersionResource) string { - return getNamespacesSelector(resource, is.namespace, "==") +func (is *IncludeSelector) GetNamespacesSelectors(resource *schema.GroupVersionResource) []string { + fieldSelectors := []string{} + for _, n := range strings.Split(is.namespace, ",") { + if n != "" { + fieldSelectors = append(fieldSelectors, getNamespacesSelector(resource, n, "==")) + } + } + return fieldSelectors } func getNamespacesSelector(resource *schema.GroupVersionResource, ns, operator string) string { - fieldSelectors := "" fieldSelector := "metadata." if resource.Resource == "namespaces" { fieldSelector += "name" @@ -52,12 +64,6 @@ func getNamespacesSelector(resource *schema.GroupVersionResource, ns, operator s } else { return "" } - namespacesSlice := strings.Split(ns, ",") - for _, n := range namespacesSlice { - if n != "" { - fieldSelectors += fmt.Sprintf("%s%s%s,", fieldSelector, operator, n) - } - } - return fieldSelectors + return fmt.Sprintf("%s%s%s", fieldSelector, operator, ns) } diff --git a/resourcehandler/fieldselector_test.go b/resourcehandler/fieldselector_test.go index 147818e0..5d3058af 100644 --- a/resourcehandler/fieldselector_test.go +++ b/resourcehandler/fieldselector_test.go @@ -10,6 +10,30 @@ import ( func TestGetNamespacesSelector(t *testing.T) { k8sinterface.InitializeMapResourcesMock() - assert.Equal(t, "metadata.namespace==default,", getNamespacesSelector(&schema.GroupVersionResource{Version: "v1", Resource: "pods"}, "default,", "==")) - assert.Equal(t, "", getNamespacesSelector(&schema.GroupVersionResource{Version: "v1", Resource: "nodes"}, "default,", "==")) + assert.Equal(t, "metadata.namespace==default", getNamespacesSelector(&schema.GroupVersionResource{Version: "v1", Resource: "pods"}, "default", "==")) + assert.Equal(t, "", getNamespacesSelector(&schema.GroupVersionResource{Version: "v1", Resource: "nodes"}, "default", "==")) +} + +func TestExcludedNamespacesSelectors(t *testing.T) { + es := NewExcludeSelector("default,ingress") + selectors := es.GetNamespacesSelectors(&schema.GroupVersionResource{Resource: "pods"}) + assert.Equal(t, 1, len(selectors)) + assert.Equal(t, "metadata.namespace!=default,metadata.namespace!=ingress,", selectors[0]) + + selectors2 := es.GetNamespacesSelectors(&schema.GroupVersionResource{Resource: "namespaces"}) + assert.Equal(t, 1, len(selectors2)) + assert.Equal(t, "metadata.name!=default,metadata.name!=ingress,", selectors2[0]) +} + +func TestIncludeNamespacesSelectors(t *testing.T) { + is := NewIncludeSelector("default,ingress") + selectors := is.GetNamespacesSelectors(&schema.GroupVersionResource{Resource: "pods"}) + assert.Equal(t, 2, len(selectors)) + assert.Equal(t, "metadata.namespace==default", selectors[0]) + assert.Equal(t, "metadata.namespace==ingress", selectors[1]) + + selectors2 := is.GetNamespacesSelectors(&schema.GroupVersionResource{Resource: "namespaces"}) + assert.Equal(t, 2, len(selectors2)) + assert.Equal(t, "metadata.name==default", selectors2[0]) + assert.Equal(t, "metadata.name==ingress", selectors2[1]) } diff --git a/resourcehandler/k8sresources.go b/resourcehandler/k8sresources.go index 7f948ab2..149df06d 100644 --- a/resourcehandler/k8sresources.go +++ b/resourcehandler/k8sresources.go @@ -82,32 +82,38 @@ func (k8sHandler *K8sResourceHandler) pullResources(k8sResources *cautils.K8SRes } func (k8sHandler *K8sResourceHandler) pullSingleResource(resource *schema.GroupVersionResource, namespace string, labels map[string]string) ([]unstructured.Unstructured, error) { - + resourceList := []unstructured.Unstructured{} // set labels listOptions := metav1.ListOptions{} + fieldSelectors := k8sHandler.fieldSelector.GetNamespacesSelectors(resource) + for i := range fieldSelectors { - listOptions.FieldSelector += k8sHandler.fieldSelector.GetNamespacesSelector(resource) + listOptions.FieldSelector = fieldSelectors[i] + + if len(labels) > 0 { + set := k8slabels.Set(labels) + listOptions.LabelSelector = set.AsSelector().String() + } + + // set dynamic object + var clientResource dynamic.ResourceInterface + if namespace != "" && k8sinterface.IsNamespaceScope(resource) { + clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource).Namespace(namespace) + } else { + clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource) + } + + // list resources + result, err := clientResource.List(context.Background(), listOptions) + if err != nil || result == nil { + return nil, fmt.Errorf("failed to get resource: %v, namespace: %s, labelSelector: %v, reason: %v", resource, namespace, listOptions.LabelSelector, err) + } + + resourceList = append(resourceList, result.Items...) - if len(labels) > 0 { - set := k8slabels.Set(labels) - listOptions.LabelSelector = set.AsSelector().String() } - // set dynamic object - var clientResource dynamic.ResourceInterface - if namespace != "" && k8sinterface.IsNamespaceScope(resource) { - clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource).Namespace(namespace) - } else { - clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource) - } - - // list resources - result, err := clientResource.List(context.Background(), listOptions) - if err != nil { - return nil, fmt.Errorf("failed to get resource: %v, namespace: %s, labelSelector: %v, reason: %s", resource, namespace, listOptions.LabelSelector, err.Error()) - } - - return result.Items, nil + return resourceList, nil } func ConvertMapListToMeta(resourceMap []map[string]interface{}) []workloadinterface.IMetadata {