Skip to content

Commit 5a2edd6

Browse files
authored
feat: add support for ignoring nodes via label (#128)
1 parent 59c1c0d commit 5a2edd6

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

operator/internal/controller/cluster_state_v2.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,18 +530,31 @@ func (np *NodePicker) SelectNodes(s SkyhookNodes) []wrapper.SkyhookNode {
530530
return np.selectNodesWithCompartments(s, compartments, tolerations)
531531
}
532532

533+
// CheckNodeIgnoreLabel checks if a node has the ignore label set to true
534+
func CheckNodeIgnoreLabel(node wrapper.SkyhookNode) bool {
535+
ignoreLabel := fmt.Sprintf("%s/ignore", v1alpha1.METADATA_PREFIX)
536+
if val, ok := node.GetNode().Labels[ignoreLabel]; ok && val == "true" {
537+
return true
538+
}
539+
return false
540+
}
541+
533542
// selectNodesWithCompartments selects nodes using compartment-based batch processing
534543
func (np *NodePicker) selectNodesWithCompartments(s SkyhookNodes, compartments map[string]*wrapper.Compartment, tolerations []corev1.Toleration) []wrapper.SkyhookNode {
535544
selectedNodes := make([]wrapper.SkyhookNode, 0)
536545
nodesWithTaintTolerationIssue := make([]string, 0)
546+
ignoredNodes := make([]string, 0)
537547

538-
// First, check ALL nodes for taint issues to set the condition correctly
539-
// This ensures the condition reflects the true state even when no batch is being processed
548+
// First, check ALL nodes for taint and ignore issues to set the conditions correctly
549+
// This ensures the conditions reflect the true state even when no batch is being processed
540550
for _, compartment := range compartments {
541551
for _, node := range compartment.GetNodes() {
542552
if !CheckTaintToleration(tolerations, node.GetNode().Spec.Taints) {
543553
nodesWithTaintTolerationIssue = append(nodesWithTaintTolerationIssue, node.GetNode().Name)
544554
}
555+
if CheckNodeIgnoreLabel(node) {
556+
ignoredNodes = append(ignoredNodes, node.GetNode().Name)
557+
}
545558
}
546559
}
547560

@@ -550,6 +563,11 @@ func (np *NodePicker) selectNodesWithCompartments(s SkyhookNodes, compartments m
550563
batchNodes := compartment.GetNodesForNextBatch()
551564

552565
for _, node := range batchNodes {
566+
// Check if node is ignored
567+
if CheckNodeIgnoreLabel(node) {
568+
node.SetStatus(v1alpha1.StatusBlocked)
569+
continue
570+
}
553571
// Check taint toleration
554572
if CheckTaintToleration(tolerations, node.GetNode().Spec.Taints) {
555573
selectedNodes = append(selectedNodes, node)
@@ -562,6 +580,8 @@ func (np *NodePicker) selectNodesWithCompartments(s SkyhookNodes, compartments m
562580

563581
// Add condition about taint toleration issues
564582
np.updateTaintToleranceCondition(s, nodesWithTaintTolerationIssue)
583+
// Add condition about ignored nodes
584+
np.updateIgnoredNodesCondition(s, ignoredNodes)
565585

566586
return selectedNodes
567587
}
@@ -587,6 +607,27 @@ func (np *NodePicker) updateTaintToleranceCondition(s SkyhookNodes, nodesWithTai
587607
}
588608
}
589609

610+
// updateIgnoredNodesCondition updates the ignored nodes condition on the skyhook
611+
func (np *NodePicker) updateIgnoredNodesCondition(s SkyhookNodes, ignoredNodes []string) {
612+
if len(ignoredNodes) > 0 {
613+
s.GetSkyhook().AddCondition(metav1.Condition{
614+
Type: fmt.Sprintf("%s/NodesIgnored", v1alpha1.METADATA_PREFIX),
615+
Status: metav1.ConditionTrue,
616+
Reason: "NodesIgnored",
617+
Message: fmt.Sprintf("Node [%s] has ignore label set. Skipping.", strings.Join(ignoredNodes, ", ")),
618+
LastTransitionTime: metav1.Now(),
619+
})
620+
} else {
621+
s.GetSkyhook().AddCondition(metav1.Condition{
622+
Type: fmt.Sprintf("%s/NodesIgnored", v1alpha1.METADATA_PREFIX),
623+
Status: metav1.ConditionFalse,
624+
Reason: "NodesIgnored",
625+
Message: "No nodes have ignore label set.",
626+
LastTransitionTime: metav1.Now(),
627+
})
628+
}
629+
}
630+
590631
// for node/package source of true, its on the node (we true to reflect this on the skyhook status)
591632
// for SCR true, we need to look at all nodes and compare state to current SCR. This should be reflected in the SCR too.
592633

operator/internal/controller/cluster_state_v2_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,33 @@ var _ = Describe("cluster state v2 tests", func() {
114114

115115
Expect(CheckTaintToleration(tolerations, taints)).To(BeTrue())
116116
})
117+
118+
It("When node has ignore label it is blocked", func() {
119+
node := &corev1.Node{
120+
ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: map[string]string{v1alpha1.METADATA_PREFIX + "/ignore": "true"}},
121+
}
122+
skyhookNode, err := wrapper.NewSkyhookNode(node, &v1alpha1.Skyhook{})
123+
Expect(err).ToNot(HaveOccurred())
124+
Expect(CheckNodeIgnoreLabel(skyhookNode)).To(BeTrue())
125+
})
126+
127+
It("When node does not have ignore label it is not blocked", func() {
128+
node := &corev1.Node{
129+
ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: map[string]string{}},
130+
}
131+
skyhookNode, err := wrapper.NewSkyhookNode(node, &v1alpha1.Skyhook{})
132+
Expect(err).ToNot(HaveOccurred())
133+
Expect(CheckNodeIgnoreLabel(skyhookNode)).To(BeFalse())
134+
})
135+
136+
It("When node has ignore label set to false it is not blocked", func() {
137+
node := &corev1.Node{
138+
ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: map[string]string{v1alpha1.METADATA_PREFIX + "/ignore": "false"}},
139+
}
140+
skyhookNode, err := wrapper.NewSkyhookNode(node, &v1alpha1.Skyhook{})
141+
Expect(err).ToNot(HaveOccurred())
142+
Expect(CheckNodeIgnoreLabel(skyhookNode)).To(BeFalse())
143+
})
117144
})
118145

119146
// --- Add GetNextSkyhook tests ---

0 commit comments

Comments
 (0)