...

Source file src/edge-infra.dev/pkg/edge/api/types/pallet_types.go

Documentation: edge-infra.dev/pkg/edge/api/types

     1  package types
     2  
     3  import (
     4  	"k8s.io/apimachinery/pkg/labels"
     5  
     6  	"edge-infra.dev/pkg/edge/compatibility"
     7  	"edge-infra.dev/pkg/k8s/unstructured"
     8  )
     9  
    10  type Pallet struct {
    11  	Name            string
    12  	MinFleetVersion string
    13  	filter          *ManifestSelector
    14  }
    15  
    16  // NewPallet creates a new Pallet with the given name, minimum fleet version and
    17  // manifest filters
    18  func NewPallet(name, minFleetVersion string, filters ...ManifestSelectorOption) Pallet {
    19  	selector := &ManifestSelector{}
    20  	for _, opt := range filters {
    21  		opt(selector)
    22  	}
    23  
    24  	return Pallet{
    25  		Name:            name,
    26  		MinFleetVersion: minFleetVersion,
    27  		filter:          selector,
    28  	}
    29  }
    30  
    31  // IsDeployable returns true if the pallet is deployable on the given fleet
    32  // version
    33  func (p *Pallet) IsDeployable(fleetVersion string) (bool, error) {
    34  	deploy, err := compatibility.Compare(compatibility.LessThanOrEqual, p.MinFleetVersion, fleetVersion)
    35  	if err != nil {
    36  		return false, err
    37  	}
    38  
    39  	return deploy, nil
    40  }
    41  
    42  // IsManifestDeployable returns true if the unstructured object is deployable
    43  // based on the pallet's manifest filters
    44  func (p *Pallet) IsManifestDeployable(uns *unstructured.Unstructured) bool {
    45  	return p.filter.Matches(uns)
    46  }
    47  
    48  // Selector is an interface for filtering resources based on a string field
    49  type Selector interface {
    50  	Matches(string) bool
    51  }
    52  
    53  // GenericSelector is a simple selector that matches targets based on an Include
    54  // and Exclude list. If Include is empty, all targets are included that do not
    55  // appear in the Exclude list
    56  type GenericSelector struct {
    57  	Include []string
    58  	Exclude []string
    59  }
    60  
    61  // Matches returns true if the target is in the Include list and not in the
    62  // Exclude list. If Include is empty, it matches all targets that are not in the
    63  // Exclude list
    64  func (g *GenericSelector) Matches(target string) bool {
    65  	for _, exclude := range g.Exclude {
    66  		if exclude == target {
    67  			return false
    68  		}
    69  	}
    70  	// if include list is empty, it matches
    71  	if len(g.Include) == 0 {
    72  		return true
    73  	}
    74  
    75  	for _, include := range g.Include {
    76  		if include == target {
    77  			return true
    78  		}
    79  	}
    80  	// If namespace is not in Include list, it does not match
    81  	return false
    82  }
    83  
    84  // ManifestSelector is a selector for filtering resources based on a label
    85  // selector, kind selector, and namespace selector
    86  type ManifestSelector struct {
    87  	// LabelSelector filters results by label. Use labels.Parse() to set from
    88  	// raw string form
    89  	LabelSelector labels.Selector
    90  	// KindSelector filters results by kind
    91  	KindSelector Selector
    92  	// NamespaceSelector filters results by namespace
    93  	NamespaceSelector Selector
    94  }
    95  
    96  // Matches returns true if the unstructured object matches the label, kind, and
    97  // namespace selectors
    98  func (m *ManifestSelector) Matches(uns *unstructured.Unstructured) bool {
    99  	if m.LabelSelector != nil && !m.LabelSelector.Matches(labels.Set(uns.GetLabels())) {
   100  		return false
   101  	}
   102  
   103  	if m.KindSelector != nil && !m.KindSelector.Matches(uns.GetKind()) {
   104  		return false
   105  	}
   106  
   107  	return m.NamespaceSelector == nil || m.NamespaceSelector.Matches(uns.GetNamespace())
   108  }
   109  
   110  // ManifestSelectorOption is a functional option for configuring a
   111  // ManifestSelector
   112  type ManifestSelectorOption func(*ManifestSelector)
   113  
   114  // WithLabelSelector sets the label selector for the ManifestSelector
   115  func WithLabelSelector(s labels.Selector) ManifestSelectorOption {
   116  	return func(f *ManifestSelector) {
   117  		f.LabelSelector = s
   118  	}
   119  }
   120  
   121  // WithKindSelector sets the kind selector for the ManifestSelector
   122  func WithKindSelector(s Selector) ManifestSelectorOption {
   123  	return func(f *ManifestSelector) {
   124  		f.KindSelector = s
   125  	}
   126  }
   127  
   128  // WithNamespaceSelector sets the namespace selector for the ManifestSelector
   129  func WithNamespaceSelector(s Selector) ManifestSelectorOption {
   130  	return func(f *ManifestSelector) {
   131  		f.NamespaceSelector = s
   132  	}
   133  }
   134  

View as plain text