github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/selection/labels.go (about)

     1  package selection
     2  
     3  import (
     4  	"errors"
     5  	"sort"
     6  	"strings"
     7  
     8  	k8slabels "k8s.io/apimachinery/pkg/labels"
     9  	k8svalidation "k8s.io/apimachinery/pkg/util/validation"
    10  )
    11  
    12  // LabelSelector is a type that performs matching against a set of labels.
    13  type LabelSelector interface {
    14  	// Matches checks whether or not a set of labels is matched by the selector.
    15  	Matches(labels map[string]string) bool
    16  }
    17  
    18  // labelSelector is the internal selector implementation. Internally it uses the
    19  // Kubernetes label selection infrastructure.
    20  type labelSelector struct {
    21  	// k8sLabelSelector is the underlying Kubernetes label selector.
    22  	k8sLabelSelector k8slabels.Selector
    23  }
    24  
    25  // Matches implements Selector.Matches.
    26  func (s *labelSelector) Matches(labels map[string]string) bool {
    27  	return s.k8sLabelSelector.Matches(k8slabels.Set(labels))
    28  }
    29  
    30  // ParseLabelSelector performs label selector parsing. The syntax is currently
    31  // the same as that for Kubernetes.
    32  func ParseLabelSelector(selector string) (LabelSelector, error) {
    33  	// Parse the selector using the Kubernetes label infrastructure.
    34  	k8sLabelSelector, err := k8slabels.Parse(selector)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  
    39  	// Wrap up the Kubernetes selector.
    40  	return &labelSelector{k8sLabelSelector}, nil
    41  }
    42  
    43  // ExtractAndSortLabelKeys extracts a list of keys from the label set and sorts
    44  // them.
    45  func ExtractAndSortLabelKeys(labels map[string]string) []string {
    46  	// Avoid allocation in the event that there are no labels.
    47  	if len(labels) == 0 {
    48  		return nil
    49  	}
    50  
    51  	// Create and populate the key slice.
    52  	keys := make([]string, 0, len(labels))
    53  	for key := range labels {
    54  		keys = append(keys, key)
    55  	}
    56  
    57  	// Sort keys.
    58  	sort.Strings(keys)
    59  
    60  	// Done.
    61  	return keys
    62  }
    63  
    64  // EnsureLabelKeyValid verifies that a key conforms to label key requirements.
    65  // These requirements are currently the same as those for Kubernetes label keys.
    66  func EnsureLabelKeyValid(key string) error {
    67  	// Perform validation.
    68  	if errs := k8svalidation.IsQualifiedName(key); len(errs) > 0 {
    69  		return errors.New(strings.Join(errs, ", "))
    70  	}
    71  
    72  	// Success.
    73  	return nil
    74  }
    75  
    76  // EnsureLabelValueValid verifies that a value conforms to label value
    77  // requirements. These requirements are currently the same as those for
    78  // Kubernetes label values.
    79  func EnsureLabelValueValid(value string) error {
    80  	// Perform validation.
    81  	if errs := k8svalidation.IsValidLabelValue(value); len(errs) > 0 {
    82  		return errors.New(strings.Join(errs, ", "))
    83  	}
    84  
    85  	// Success.
    86  	return nil
    87  }