Skip to content

Commit fe4b853

Browse files
authored
Add support for kubernetes node pool taints (#363)
* CLOUD-5710 - Add taints to nodepools * CLOUD-5710 - remove unused fields from tests * CLOUD-5710 - remove omitempty * CLOUD-5710 - remove update omit empty to prevent deletion of taints
1 parent cee0ea2 commit fe4b853

File tree

2 files changed

+128
-1
lines changed

2 files changed

+128
-1
lines changed

kubernetes.go

+10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ type Cluster struct {
5858
NodePools []NodePool `json:"node_pools"`
5959
}
6060

61+
// Taint represents a Kubernetes taint that can be applied to nodes in a node pool
62+
type Taint struct {
63+
Key string `json:"key"`
64+
Value string `json:"value"`
65+
Effect string `json:"effect"`
66+
}
67+
6168
// NodePool represents a pool of nodes that are grouped by their label and plan type
6269
type NodePool struct {
6370
ID string `json:"id"`
@@ -72,6 +79,7 @@ type NodePool struct {
7279
AutoScaler bool `json:"auto_scaler"`
7380
Tag string `json:"tag"`
7481
Labels map[string]string `json:"labels"`
82+
Taints []Taint `json:"taints"`
7583
Nodes []Node `json:"nodes"`
7684
}
7785

@@ -113,6 +121,7 @@ type NodePoolReq struct {
113121
MaxNodes int `json:"max_nodes,omitempty"`
114122
AutoScaler *bool `json:"auto_scaler"`
115123
Labels map[string]string `json:"labels,omitempty"`
124+
Taints []Taint `json:"taints,omitempty"`
116125
}
117126

118127
// NodePoolReqUpdate struct used to update a node pool
@@ -123,6 +132,7 @@ type NodePoolReqUpdate struct {
123132
MaxNodes int `json:"max_nodes,omitempty"`
124133
AutoScaler *bool `json:"auto_scaler,omitempty"`
125134
Labels map[string]string `json:"labels,omitempty"`
135+
Taints []Taint `json:"taints"`
126136
}
127137

128138
type vkeClustersBase struct {

kubernetes_test.go

+118-1
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,13 @@ func TestKubernetesHandler_CreateNodePool(t *testing.T) {
382382
"vultr.com/label1": "value1",
383383
"vultr.com/label2": "value2"
384384
},
385+
"taints": [
386+
{
387+
"key": "gpu",
388+
"value": "test",
389+
"effect": "NoSchedule"
390+
}
391+
],
385392
"nodes": [
386393
{
387394
"id": "3e1ca1e0-25be-4977-907a-3dee42b9bb15",
@@ -404,6 +411,13 @@ func TestKubernetesHandler_CreateNodePool(t *testing.T) {
404411
"vultr.com/label1": "value1",
405412
"vultr.com/label2": "value2",
406413
},
414+
Taints: []Taint{
415+
{
416+
Key: "gpu",
417+
Value: "test",
418+
Effect: "NoSchedule",
419+
},
420+
},
407421
}
408422
np, _, err := client.Kubernetes.CreateNodePool(ctx, "1", createReq)
409423
if err != nil {
@@ -425,6 +439,13 @@ func TestKubernetesHandler_CreateNodePool(t *testing.T) {
425439
"vultr.com/label1": "value1",
426440
"vultr.com/label2": "value2",
427441
},
442+
Taints: []Taint{
443+
{
444+
Key: "gpu",
445+
Value: "test",
446+
Effect: "NoSchedule",
447+
},
448+
},
428449
Nodes: []Node{
429450
{
430451
ID: "3e1ca1e0-25be-4977-907a-3dee42b9bb15",
@@ -464,6 +485,13 @@ func TestKubernetesHandler_GetNodePool(t *testing.T) {
464485
"max_nodes": 2,
465486
"auto_scaler": true,
466487
"tag": "mytag",
488+
"taints": [
489+
{
490+
"key": "gpu",
491+
"value": "test",
492+
"effect": "NoSchedule"
493+
}
494+
],
467495
"nodes": [
468496
{
469497
"id": "3e1ca1e0-25be-4977-907a-3dee42b9bb15",
@@ -493,6 +521,13 @@ func TestKubernetesHandler_GetNodePool(t *testing.T) {
493521
MinNodes: 1,
494522
MaxNodes: 2,
495523
AutoScaler: true,
524+
Taints: []Taint{
525+
{
526+
Key: "gpu",
527+
Value: "test",
528+
Effect: "NoSchedule",
529+
},
530+
},
496531
Nodes: []Node{
497532
{
498533
ID: "3e1ca1e0-25be-4977-907a-3dee42b9bb15",
@@ -532,6 +567,13 @@ func TestKubernetesHandler_ListNodePools(t *testing.T) {
532567
"max_nodes": 2,
533568
"auto_scaler": true,
534569
"tag": "mytag",
570+
"taints": [
571+
{
572+
"key": "gpu",
573+
"value": "test",
574+
"effect": "NoSchedule"
575+
}
576+
],
535577
"nodes": [
536578
{
537579
"id": "3e1ca1e0-25be-4977-907a-3dee42b9bb15",
@@ -569,6 +611,13 @@ func TestKubernetesHandler_ListNodePools(t *testing.T) {
569611
MinNodes: 1,
570612
MaxNodes: 2,
571613
AutoScaler: true,
614+
Taints: []Taint{
615+
{
616+
Key: "gpu",
617+
Value: "test",
618+
Effect: "NoSchedule",
619+
},
620+
},
572621
Nodes: []Node{
573622
{
574623
ID: "3e1ca1e0-25be-4977-907a-3dee42b9bb15",
@@ -621,6 +670,13 @@ func TestKubernetesHandler_UpdateNodePool(t *testing.T) {
621670
"max_nodes": 2,
622671
"auto_scaler": true,
623672
"tag": "mytag",
673+
"taints": [
674+
{
675+
"key": "gpu",
676+
"value": "updated-test",
677+
"effect": "NoSchedule"
678+
}
679+
],
624680
"nodes": [
625681
{
626682
"id": "f2e11430-76e5-4dc6-a1c9-ef5682c21ddf",
@@ -633,7 +689,20 @@ func TestKubernetesHandler_UpdateNodePool(t *testing.T) {
633689
}`
634690
fmt.Fprint(writer, response)
635691
})
636-
update := NodePoolReqUpdate{NodeQuantity: 1}
692+
693+
taints := []Taint{
694+
{
695+
Key: "gpu",
696+
Value: "updated-test",
697+
Effect: "NoSchedule",
698+
},
699+
}
700+
701+
update := NodePoolReqUpdate{
702+
NodeQuantity: 1,
703+
Taints: taints,
704+
}
705+
637706
response, _, err := client.Kubernetes.UpdateNodePool(ctx, "1", "2", &update)
638707
if err != nil {
639708
t.Errorf("Kubernetes.UpdateNodePool returned %+v", err)
@@ -651,6 +720,7 @@ func TestKubernetesHandler_UpdateNodePool(t *testing.T) {
651720
MaxNodes: 2,
652721
AutoScaler: true,
653722
Tag: "mytag",
723+
Taints: taints,
654724
Nodes: []Node{
655725
{
656726
ID: "f2e11430-76e5-4dc6-a1c9-ef5682c21ddf",
@@ -810,3 +880,50 @@ func TestKubernetesHandler_Upgrade(t *testing.T) {
810880
t.Errorf("Kubernetes.StartUpgrade returned %+v", err)
811881
}
812882
}
883+
884+
func TestTaintStructForNodePool(t *testing.T) {
885+
setup()
886+
defer teardown()
887+
888+
// Test creating a node pool with taints
889+
taints := []Taint{
890+
{
891+
Key: "key1",
892+
Value: "value1",
893+
Effect: "NoSchedule",
894+
},
895+
{
896+
Key: "key2",
897+
Value: "value2",
898+
Effect: "NoExecute",
899+
},
900+
}
901+
902+
// Construct a NodePoolReq with taints
903+
nodePoolReq := &NodePoolReq{
904+
Taints: taints,
905+
}
906+
907+
// Test that the taints are properly included in the struct
908+
if len(nodePoolReq.Taints) != 2 {
909+
t.Errorf("Expected 2 taints in the NodePoolReq struct, got %d", len(nodePoolReq.Taints))
910+
}
911+
912+
// Test that the taints values are correct
913+
if nodePoolReq.Taints[0].Key != "key1" || nodePoolReq.Taints[0].Value != "value1" || nodePoolReq.Taints[0].Effect != "NoSchedule" {
914+
t.Errorf("First taint values don't match expected values, got %+v", nodePoolReq.Taints[0])
915+
}
916+
917+
if nodePoolReq.Taints[1].Key != "key2" || nodePoolReq.Taints[1].Value != "value2" || nodePoolReq.Taints[1].Effect != "NoExecute" {
918+
t.Errorf("Second taint values don't match expected values, got %+v", nodePoolReq.Taints[1])
919+
}
920+
921+
// Test NodePoolReqUpdate with taints
922+
updateReq := &NodePoolReqUpdate{
923+
Taints: taints,
924+
}
925+
926+
if len(updateReq.Taints) != 2 {
927+
t.Errorf("Expected 2 taints in the NodePoolReqUpdate struct, got %d", len(updateReq.Taints))
928+
}
929+
}

0 commit comments

Comments
 (0)