github.com/oam-dev/kubevela@v1.9.11/pkg/utils/filters/filter.go (about)

     1  /*
     2  Copyright 2022 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package filters
    18  
    19  import (
    20  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    21  	"k8s.io/apimachinery/pkg/runtime"
    22  
    23  	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
    24  	"github.com/oam-dev/kubevela/pkg/utils/addon"
    25  )
    26  
    27  // Filter is used to filter Unstructured objects. It is basically a func(unstructured.Unstructured) bool.
    28  type Filter func(unstructured.Unstructured) bool
    29  
    30  // Apply applies all the provided filters to a given object.
    31  // Then returns if the object is filtered out or not.
    32  // Returns true if this object is kept, otherwise false.
    33  func Apply(obj unstructured.Unstructured, filters ...Filter) bool {
    34  	// Apply all filters
    35  	for _, filter := range filters {
    36  		// If filtered out by one of the filters
    37  		if !filter(obj) {
    38  			return false
    39  		}
    40  	}
    41  
    42  	// All filters have kept this item
    43  	return true
    44  }
    45  
    46  // ApplyToList applies all the provided filters to a UnstructuredList.
    47  // It only keeps items that pass all the filters.
    48  func ApplyToList(list unstructured.UnstructuredList, filters ...Filter) unstructured.UnstructuredList {
    49  	filteredList := unstructured.UnstructuredList{Object: list.Object}
    50  
    51  	// Apply filters to each item in the list
    52  	for _, u := range list.Items {
    53  		kept := Apply(u, filters...)
    54  		if !kept {
    55  			continue
    56  		}
    57  
    58  		// Item that passed filters
    59  		filteredList.Items = append(filteredList.Items, u)
    60  	}
    61  
    62  	return filteredList
    63  }
    64  
    65  // KeepAll returns a filter that keeps everything
    66  func KeepAll() Filter {
    67  	return func(unstructured.Unstructured) bool {
    68  		return true
    69  	}
    70  }
    71  
    72  // KeepNone returns a filter that filters out everything
    73  func KeepNone() Filter {
    74  	return func(unstructured.Unstructured) bool {
    75  		return false
    76  	}
    77  }
    78  
    79  // ByOwnerAddon returns a filter that filters out what does not belong to the owner addon.
    80  // Empty addon name will keep everything.
    81  func ByOwnerAddon(addonName string) Filter {
    82  	if addonName == "" {
    83  		// Empty addon name, just keep everything, no further action needed
    84  		return KeepAll()
    85  	}
    86  
    87  	// Filter by which addon installed it by owner reference
    88  	// only keep the ones that belong to the addon
    89  	return func(obj unstructured.Unstructured) bool {
    90  		ownerRefs := obj.GetOwnerReferences()
    91  		isOwnedBy := false
    92  		for _, ownerRef := range ownerRefs {
    93  			if ownerRef.Name == addon.Addon2AppName(addonName) {
    94  				isOwnedBy = true
    95  				break
    96  			}
    97  		}
    98  		return isOwnedBy
    99  	}
   100  }
   101  
   102  // ByName returns a filter that matches the given name.
   103  // Empty name will keep everything.
   104  func ByName(name string) Filter {
   105  	// Keep everything
   106  	if name == "" {
   107  		return KeepAll()
   108  	}
   109  
   110  	// Filter by name
   111  	return func(obj unstructured.Unstructured) bool {
   112  		return obj.GetName() == name
   113  	}
   114  }
   115  
   116  // ByAppliedWorkload returns a filter that only keeps trait definitions that applies to the given workload.
   117  // Empty workload name will keep everything.
   118  func ByAppliedWorkload(workload string) Filter {
   119  	// Keep everything
   120  	if workload == "" {
   121  		return KeepAll()
   122  	}
   123  
   124  	return func(obj unstructured.Unstructured) bool {
   125  		traitDef := &v1beta1.TraitDefinition{}
   126  		if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, traitDef); err != nil {
   127  			return false
   128  		}
   129  
   130  		// Search for provided workload
   131  		// If the trait definitions applies to the given workload, then it is kept.
   132  		for _, w := range traitDef.Spec.AppliesToWorkloads {
   133  			if w == workload || w == "*" {
   134  				return true
   135  			}
   136  		}
   137  
   138  		return false
   139  	}
   140  }