Skip to content

Commit

Permalink
Clean up and refactor to be consistent to v1alpha5 API
Browse files Browse the repository at this point in the history
  • Loading branch information
felix-zhe-huang committed Jan 23, 2022
1 parent 80a5ae6 commit 28a7716
Show file tree
Hide file tree
Showing 17 changed files with 225 additions and 436 deletions.
79 changes: 25 additions & 54 deletions charts/karpenter/crds/karpenter.sh_provisioners.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,62 +78,33 @@ spec:
requirements:
description: Requirements are layered with Labels and applied to every
node.
properties:
allows:
additionalProperties:
description: Set is a logical set of string values for the requirements.
It supports representations using complement operator. e.g.,
if C={"A", "B"}, setting isComplement = true means C' contains
every possible string values other than "A" and "B"
properties:
Members:
additionalProperties:
description: Empty is public since it is used by some
internal API objects for conversions between external
string arrays and internal sets, and conversion logic
requires public types today.
type: object
description: sets.String is a set of strings, implemented
via map[string]struct{} for minimal memory consumption.
type: object
allows:
type: boolean
type: object
type: object
requirements:
additionalProperties:
items:
description: A node selector requirement is a selector that contains
values, a key, and an operator that relates the key and values.
properties:
key:
description: The label key that the selector applies to.
type: string
operator:
description: Represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and
Lt.
type: string
values:
description: An array of string values. If the operator is In
or NotIn, the values array must be non-empty. If the operator
is Exists or DoesNotExist, the values array must be empty.
If the operator is Gt or Lt, the values array must have a
single element, which will be interpreted as an integer. This
array is replaced during a strategic merge patch.
items:
description: A node selector requirement is a selector that
contains values, a key, and an operator that relates the
key and values.
properties:
key:
description: The label key that the selector applies to.
type: string
operator:
description: Represents a key's relationship to a set
of values. Valid operators are In, NotIn, Exists, DoesNotExist.
Gt, and Lt.
type: string
values:
description: An array of string values. If the operator
is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. If the operator is Gt or Lt, the
values array must have a single element, which will
be interpreted as an integer. This array is replaced
during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: string
type: array
description: Ground truth record of requirements
type: object
type: object
required:
- key
- operator
type: object
type: array
taints:
description: Taints will be applied to every node launched by the
Provisioner. If specified, the provisioner will not provision nodes
Expand Down
6 changes: 3 additions & 3 deletions pkg/apis/provisioning/v1alpha5/constraints.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type Constraints struct {
// +optional
Taints Taints `json:"taints,omitempty"`
// Requirements are layered with Labels and applied to every node.
Requirements *Requirements `json:"requirements,omitempty"`
Requirements *Requirements `json:"requirements,inline,omitempty"`
// KubeletConfiguration are options passed to the kubelet when provisioning nodes
//+optional
KubeletConfiguration KubeletConfiguration `json:"kubeletConfiguration,omitempty"`
Expand All @@ -49,7 +49,7 @@ func (c *Constraints) ValidatePod(pod *v1.Pod) error {
return err
}
// Test if pod requirements are valid
podRequirements := PodRequirements(pod)
podRequirements := NewRequirements(PodRequirements(pod)...)
if errs := podRequirements.Validate(); errs != nil {
return fmt.Errorf("pod requirements not feasible, %v", errs)
}
Expand All @@ -63,7 +63,7 @@ func (c *Constraints) ValidatePod(pod *v1.Pod) error {
func (c *Constraints) Tighten(pod *v1.Pod) *Constraints {
return &Constraints{
Labels: c.Labels,
Requirements: c.Requirements.Merge(PodRequirements(pod)).WellKnown(),
Requirements: c.Requirements.Add(PodRequirements(pod)...).WellKnown(),
Taints: c.Taints,
Provider: c.Provider,
KubeletConfiguration: c.KubeletConfiguration,
Expand Down
16 changes: 14 additions & 2 deletions pkg/apis/provisioning/v1alpha5/provisioner_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (s *ProvisionerSpec) validate(ctx context.Context) (errs *apis.FieldError)
return errs.Also(
s.validateTTLSecondsUntilExpired(),
s.validateTTLSecondsAfterEmpty(),
s.Constraints.Validate(ctx),
s.Validate(ctx),
)
}

Expand Down Expand Up @@ -132,6 +132,18 @@ func (c *Constraints) validateTaints() (errs *apis.FieldError) {
return errs
}

// This function is used by the provisioner validation webhook to verify the provisioner requirements.
// When this function is called, the provisioner's requirments do not include the requirements from labels.
// Provisioner requirement section only support wellknown labels for now.
func (c *Constraints) validateRequirements() (errs *apis.FieldError) {
return c.Requirements.Validate()
// validate if requirement keys are well known labels
for _, key := range c.Requirements.Keys() {
if !WellKnownLabels.Has(key) {
errs = errs.Also(apis.ErrInvalidKeyName(fmt.Sprintf("%s not in %v", key, WellKnownLabels.UnsortedList()), "key"))
}
}
if err := c.Requirements.Validate(); err != nil {
errs = errs.Also(err)
}
return errs
}
Loading

0 comments on commit 28a7716

Please sign in to comment.