kubernetes.go raw
1 package govultr
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7
8 "github.com/google/go-querystring/query"
9 )
10
11 const vkePath = "/v2/kubernetes/clusters"
12
13 // KubernetesService is the interface to interact with kubernetes endpoint on the Vultr API
14 // Link : https://www.vultr.com/api/#tag/kubernetes
15 type KubernetesService interface {
16 CreateCluster(ctx context.Context, createReq *ClusterReq) (*Cluster, *http.Response, error)
17 GetCluster(ctx context.Context, id string) (*Cluster, *http.Response, error)
18 ListClusters(ctx context.Context, options *ListOptions) ([]Cluster, *Meta, *http.Response, error)
19 UpdateCluster(ctx context.Context, vkeID string, updateReq *ClusterReqUpdate) error
20 DeleteCluster(ctx context.Context, id string) error
21 DeleteClusterWithResources(ctx context.Context, id string) error
22
23 CreateNodePool(ctx context.Context, vkeID string, nodePoolReq *NodePoolReq) (*NodePool, *http.Response, error)
24 ListNodePools(ctx context.Context, vkeID string, options *ListOptions) ([]NodePool, *Meta, *http.Response, error)
25 GetNodePool(ctx context.Context, vkeID, nodePoolID string) (*NodePool, *http.Response, error)
26 UpdateNodePool(ctx context.Context, vkeID, nodePoolID string, updateReq *NodePoolReqUpdate) (*NodePool, *http.Response, error)
27 DeleteNodePool(ctx context.Context, vkeID, nodePoolID string) error
28
29 ListNodePoolLabels(ctx context.Context, vkeID, nodePoolID string) ([]NodePoolLabel, *http.Response, error)
30 CreateNodePoolLabel(ctx context.Context, vkeID string, nodePoolID string, nodePoolLabelReq *NodePoolLabelReq) (*NodePoolLabel, *http.Response, error) //nolint:lll
31 GetNodePoolLabel(ctx context.Context, vkeID string, nodePoolID string, nodePoolLabelID string) (*NodePoolLabel, *http.Response, error)
32 DeleteNodePoolLabel(ctx context.Context, vkeID string, nodePoolID string, nodePoolLabelID string) error
33
34 ListNodePoolTaints(ctx context.Context, vkeID, nodePoolID string) ([]NodePoolTaint, *http.Response, error)
35 CreateNodePoolTaint(ctx context.Context, vkeID string, nodePoolID string, nodePoolTaintReq *NodePoolTaintReq) (*NodePoolTaint, *http.Response, error) //nolint:lll
36 GetNodePoolTaint(ctx context.Context, vkeID string, nodePoolID string, nodePoolTaintID string) (*NodePoolTaint, *http.Response, error)
37 DeleteNodePoolTaint(ctx context.Context, vkeID string, nodePoolID string, nodePoolTaintID string) error
38
39 ListWorkerNodes(ctx context.Context, vkeID, nodePoolID string, options *ListOptions) ([]Node, *Meta, *http.Response, error)
40 DeleteNodePoolInstance(ctx context.Context, vkeID, nodePoolID, nodeID string) error
41 RecycleNodePoolInstance(ctx context.Context, vkeID, nodePoolID, nodeID string) error
42
43 GetKubeConfig(ctx context.Context, vkeID string) (*KubeConfig, *http.Response, error)
44 GetVersions(ctx context.Context) (*Versions, *http.Response, error)
45
46 GetUpgrades(ctx context.Context, vkeID string) ([]string, *http.Response, error)
47 Upgrade(ctx context.Context, vkeID string, body *ClusterUpgradeReq) error
48 }
49
50 // KubernetesHandler handles interaction with the kubernetes methods for the Vultr API
51 type KubernetesHandler struct {
52 client *Client
53 }
54
55 // Cluster represents a full VKE cluster
56 type Cluster struct {
57 ID string `json:"id"`
58 Label string `json:"label"`
59 DateCreated string `json:"date_created"`
60 ClusterSubnet string `json:"cluster_subnet"`
61 ServiceSubnet string `json:"service_subnet"`
62 IP string `json:"ip"`
63 Endpoint string `json:"endpoint"`
64 Version string `json:"version"`
65 Region string `json:"region"`
66 Status string `json:"status"`
67 HAControlPlanes bool `json:"ha_controlplanes"`
68 FirewallGroupID string `json:"firewall_group_id"`
69 NodePools []NodePool `json:"node_pools"`
70 }
71
72 // Taint represents a kubernetes taint that can be applied to nodes in a node pool
73 type Taint struct {
74 Key string `json:"key"`
75 Value string `json:"value"`
76 Effect string `json:"effect"`
77 }
78
79 // NodePool represents a pool of nodes that are grouped by their label and plan type
80 type NodePool struct {
81 ID string `json:"id"`
82 DateCreated string `json:"date_created"`
83 DateUpdated string `json:"date_updated"`
84 Label string `json:"label"`
85 Plan string `json:"plan"`
86 Status string `json:"status"`
87 NodeQuantity int `json:"node_quantity"`
88 MinNodes int `json:"min_nodes"`
89 MaxNodes int `json:"max_nodes"`
90 AutoScaler bool `json:"auto_scaler"`
91 UserData string `json:"user_data"`
92 Tag string `json:"tag"`
93 Labels map[string]string `json:"labels"`
94 Taints []Taint `json:"taints"`
95 Nodes []Node `json:"nodes"`
96 }
97
98 // Node represents a node that will live within a nodepool
99 type Node struct {
100 ID string `json:"id"`
101 DateCreated string `json:"date_created"`
102 Label string `json:"label"`
103 IP string `json:"ip,omitempty"` // Optional, may not be present in older API responses
104 Status string `json:"status"`
105 }
106
107 // KubeConfig will contain the kubeconfig b64 encoded
108 type KubeConfig struct {
109 KubeConfig string `json:"kube_config"`
110 }
111
112 // ClusterReq struct used to create a cluster
113 type ClusterReq struct {
114 Label string `json:"label"`
115 Region string `json:"region"`
116 Version string `json:"version"`
117 HAControlPlanes bool `json:"ha_controlplanes,omitempty"`
118 EnableFirewall bool `json:"enable_firewall,omitempty"`
119 VPCID string `json:"vpc_id,omitempty"`
120 NodePools []NodePoolReq `json:"node_pools"`
121 }
122
123 // ClusterReqUpdate struct used to update update a cluster
124 type ClusterReqUpdate struct {
125 Label string `json:"label"`
126 }
127
128 // NodePoolReq struct used to create a node pool
129 type NodePoolReq struct {
130 NodeQuantity int `json:"node_quantity"`
131 Label string `json:"label"`
132 Plan string `json:"plan"`
133 Tag string `json:"tag"`
134 MinNodes int `json:"min_nodes,omitempty"`
135 MaxNodes int `json:"max_nodes,omitempty"`
136 AutoScaler *bool `json:"auto_scaler"`
137 Labels map[string]string `json:"labels,omitempty"`
138 Taints []Taint `json:"taints,omitempty"`
139 UserData string `json:"user_data"`
140 }
141
142 // NodePoolReqUpdate struct used to update a node pool
143 type NodePoolReqUpdate struct {
144 NodeQuantity int `json:"node_quantity,omitempty"`
145 Tag *string `json:"tag,omitempty"`
146 MinNodes int `json:"min_nodes,omitempty"`
147 MaxNodes int `json:"max_nodes,omitempty"`
148 AutoScaler *bool `json:"auto_scaler,omitempty"`
149
150 // Deprecated: Use CreateNodePoolLabel, DeleteNodePoolLabel instead
151 Labels map[string]string `json:"labels,omitempty"`
152
153 // Deprecated: Use CreateNodePoolTaint, DeleteNodePoolTaint instead
154 Taints []Taint `json:"taints,omitempty"`
155
156 UserData *string `json:"user_data,omitempty"`
157 }
158
159 // NodePoolLabel struct used to define a NodePool Label
160 type NodePoolLabel struct {
161 ID string `json:"id"`
162 Key string `json:"key"`
163 Value string `json:"value"`
164 }
165
166 // NodePoolLabelReq struct used to create a NodePool Label
167 type NodePoolLabelReq struct {
168 Key string `json:"key"`
169 Value string `json:"value"`
170 }
171
172 // NodePoolTaint struct used to define a NodePool taint
173 type NodePoolTaint struct {
174 ID string `json:"id"`
175 Key string `json:"key"`
176 Value string `json:"value"`
177 Effect string `json:"effect"`
178 }
179
180 // NodePoolTaintReq struct used to create a NodePool taint
181 type NodePoolTaintReq struct {
182 Key string `json:"key"`
183 Value string `json:"value"`
184 Effect string `json:"effect"`
185 }
186
187 type vkeClustersBase struct {
188 VKEClusters []Cluster `json:"vke_clusters"`
189 Meta *Meta `json:"meta"`
190 }
191
192 type vkeClusterBase struct {
193 VKECluster *Cluster `json:"vke_cluster"`
194 }
195
196 type vkeNodePoolsBase struct {
197 NodePools []NodePool `json:"node_pools"`
198 Meta *Meta `json:"meta"`
199 }
200
201 type vkeNodePoolLabelsBase struct {
202 Labels []NodePoolLabel `json:"labels"`
203 }
204
205 type vkeNodePoolLabelBase struct {
206 Label *NodePoolLabel `json:"label"`
207 }
208
209 type vkeNodePoolTaintsBase struct {
210 Taints []NodePoolTaint `json:"taints"`
211 }
212
213 type vkeNodePoolTaintBase struct {
214 Taint *NodePoolTaint `json:"taint"`
215 }
216
217 type vkeWorkerNodesBase struct {
218 WorkerNodes []Node `json:"worker_nodes"`
219 Meta *Meta `json:"meta"`
220 }
221
222 type vkeNodePoolBase struct {
223 NodePool *NodePool `json:"node_pool"`
224 }
225
226 // Versions that are supported for VKE
227 type Versions struct {
228 Versions []string `json:"versions"`
229 }
230
231 // AvailableUpgrades for a given VKE cluster
232 type availableUpgrades struct {
233 AvailableUpgrades []string `json:"available_upgrades"`
234 }
235
236 // ClusterUpgradeReq struct for vke upgradse
237 type ClusterUpgradeReq struct {
238 UpgradeVersion string `json:"upgrade_version,omitempty"`
239 }
240
241 // CreateCluster will create a Kubernetes cluster.
242 func (k *KubernetesHandler) CreateCluster(ctx context.Context, createReq *ClusterReq) (*Cluster, *http.Response, error) {
243 req, err := k.client.NewRequest(ctx, http.MethodPost, vkePath, createReq)
244 if err != nil {
245 return nil, nil, err
246 }
247
248 var k8 = new(vkeClusterBase)
249 resp, err := k.client.DoWithContext(ctx, req, &k8)
250 if err != nil {
251 return nil, resp, err
252 }
253
254 return k8.VKECluster, resp, nil
255 }
256
257 // GetCluster will return a Kubernetes cluster.
258 func (k *KubernetesHandler) GetCluster(ctx context.Context, id string) (*Cluster, *http.Response, error) {
259 req, err := k.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s", vkePath, id), nil)
260 if err != nil {
261 return nil, nil, err
262 }
263
264 k8 := new(vkeClusterBase)
265 resp, err := k.client.DoWithContext(ctx, req, &k8)
266 if err != nil {
267 return nil, resp, err
268 }
269
270 return k8.VKECluster, resp, nil
271 }
272
273 // ListClusters will return all kubernetes clusters.
274 func (k *KubernetesHandler) ListClusters(ctx context.Context, options *ListOptions) ([]Cluster, *Meta, *http.Response, error) { //nolint:dupl,lll
275 req, err := k.client.NewRequest(ctx, http.MethodGet, vkePath, nil)
276 if err != nil {
277 return nil, nil, nil, err
278 }
279
280 newValues, err := query.Values(options)
281 if err != nil {
282 return nil, nil, nil, err
283 }
284
285 req.URL.RawQuery = newValues.Encode()
286
287 k8s := new(vkeClustersBase)
288 resp, err := k.client.DoWithContext(ctx, req, &k8s)
289 if err != nil {
290 return nil, nil, resp, err
291 }
292
293 return k8s.VKEClusters, k8s.Meta, resp, nil
294 }
295
296 // UpdateCluster updates label on VKE cluster
297 func (k *KubernetesHandler) UpdateCluster(ctx context.Context, vkeID string, updateReq *ClusterReqUpdate) error {
298 req, err := k.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s", vkePath, vkeID), updateReq)
299 if err != nil {
300 return err
301 }
302
303 _, err = k.client.DoWithContext(ctx, req, nil)
304 return err
305 }
306
307 // DeleteCluster will delete a Kubernetes cluster.
308 func (k *KubernetesHandler) DeleteCluster(ctx context.Context, id string) error {
309 req, err := k.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s", vkePath, id), nil)
310 if err != nil {
311 return err
312 }
313 _, err = k.client.DoWithContext(ctx, req, nil)
314 return err
315 }
316
317 // DeleteClusterWithResources will delete a Kubernetes cluster and all related resources.
318 func (k *KubernetesHandler) DeleteClusterWithResources(ctx context.Context, id string) error {
319 req, err := k.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s/delete-with-linked-resources", vkePath, id), nil)
320 if err != nil {
321 return err
322 }
323 _, err = k.client.DoWithContext(ctx, req, nil)
324 return err
325 }
326
327 // CreateNodePool creates a nodepool on a VKE cluster
328 func (k *KubernetesHandler) CreateNodePool(ctx context.Context, vkeID string, nodePoolReq *NodePoolReq) (*NodePool, *http.Response, error) {
329 req, err := k.client.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/%s/node-pools", vkePath, vkeID), nodePoolReq)
330 if err != nil {
331 return nil, nil, err
332 }
333
334 n := new(vkeNodePoolBase)
335 resp, err := k.client.DoWithContext(ctx, req, n)
336 if err != nil {
337 return nil, resp, err
338 }
339
340 return n.NodePool, resp, nil
341 }
342
343 // ListNodePools will return all nodepools for a given VKE cluster
344 func (k *KubernetesHandler) ListNodePools(ctx context.Context, vkeID string, options *ListOptions) ([]NodePool, *Meta, *http.Response, error) { //nolint:lll,dupl
345 req, err := k.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/node-pools", vkePath, vkeID), nil)
346 if err != nil {
347 return nil, nil, nil, err
348 }
349
350 newValues, err := query.Values(options)
351 if err != nil {
352 return nil, nil, nil, err
353 }
354
355 req.URL.RawQuery = newValues.Encode()
356
357 n := new(vkeNodePoolsBase)
358 resp, err := k.client.DoWithContext(ctx, req, &n)
359 if err != nil {
360 return nil, nil, resp, err
361 }
362
363 return n.NodePools, n.Meta, resp, nil
364 }
365
366 // GetNodePool will return a single nodepool
367 func (k *KubernetesHandler) GetNodePool(ctx context.Context, vkeID, nodePoolID string) (*NodePool, *http.Response, error) {
368 req, err := k.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/node-pools/%s", vkePath, vkeID, nodePoolID), nil)
369 if err != nil {
370 return nil, nil, err
371 }
372
373 n := new(vkeNodePoolBase)
374 resp, err := k.client.DoWithContext(ctx, req, &n)
375 if err != nil {
376 return nil, resp, err
377 }
378
379 return n.NodePool, resp, nil
380 }
381
382 // UpdateNodePool will allow you change the quantity of nodes within a nodepool
383 func (k *KubernetesHandler) UpdateNodePool(ctx context.Context, vkeID, nodePoolID string, updateReq *NodePoolReqUpdate) (*NodePool, *http.Response, error) { //nolint:lll
384 req, err := k.client.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s/%s/node-pools/%s", vkePath, vkeID, nodePoolID), updateReq)
385 if err != nil {
386 return nil, nil, err
387 }
388
389 np := new(vkeNodePoolBase)
390 resp, err := k.client.DoWithContext(ctx, req, np)
391 if err != nil {
392 return nil, resp, err
393 }
394
395 return np.NodePool, resp, nil
396 }
397
398 // DeleteNodePool will remove a nodepool from a VKE cluster
399 func (k *KubernetesHandler) DeleteNodePool(ctx context.Context, vkeID, nodePoolID string) error {
400 req, err := k.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s/node-pools/%s", vkePath, vkeID, nodePoolID), nil)
401 if err != nil {
402 return err
403 }
404
405 _, err = k.client.DoWithContext(ctx, req, nil)
406 return err
407 }
408
409 // ListNodePoolLabels retrieves a list of labels from a node pool
410 func (k *KubernetesHandler) ListNodePoolLabels(ctx context.Context, vkeID, nodePoolID string) ([]NodePoolLabel, *http.Response, error) {
411 uri := fmt.Sprintf("%s/%s/node-pools/%s/labels", vkePath, vkeID, nodePoolID)
412
413 req, err := k.client.NewRequest(ctx, http.MethodGet, uri, nil)
414 if err != nil {
415 return nil, nil, err
416 }
417
418 labels := new(vkeNodePoolLabelsBase)
419 resp, err := k.client.DoWithContext(ctx, req, labels)
420 if err != nil {
421 return nil, resp, err
422 }
423
424 return labels.Labels, resp, nil
425 }
426
427 // CreateNodePoolLabel creates a label on a node pool
428 func (k *KubernetesHandler) CreateNodePoolLabel(ctx context.Context, vkeID, nodePoolID string, nodePoolLabelReq *NodePoolLabelReq) (*NodePoolLabel, *http.Response, error) { //nolint:lll,dupl
429 uri := fmt.Sprintf("%s/%s/node-pools/%s/labels", vkePath, vkeID, nodePoolID)
430
431 req, err := k.client.NewRequest(ctx, http.MethodPost, uri, nodePoolLabelReq)
432 if err != nil {
433 return nil, nil, err
434 }
435
436 label := new(vkeNodePoolLabelBase)
437 resp, err := k.client.DoWithContext(ctx, req, label)
438 if err != nil {
439 return nil, resp, err
440 }
441
442 return label.Label, resp, nil
443 }
444
445 // GetNodePoolLabel retrieves a label from a node pool
446 func (k *KubernetesHandler) GetNodePoolLabel(ctx context.Context, vkeID, nodePoolID, nodePoolLabelID string) (*NodePoolLabel, *http.Response, error) { //nolint:lll
447 uri := fmt.Sprintf("%s/%s/node-pools/%s/labels/%s", vkePath, vkeID, nodePoolID, nodePoolLabelID)
448
449 req, err := k.client.NewRequest(ctx, http.MethodGet, uri, nil)
450 if err != nil {
451 return nil, nil, err
452 }
453
454 label := new(vkeNodePoolLabelBase)
455 resp, err := k.client.DoWithContext(ctx, req, label)
456 if err != nil {
457 return nil, resp, err
458 }
459
460 return label.Label, resp, nil
461 }
462
463 // DeleteNodePoolLabel deletes a label from a node pool
464 func (k *KubernetesHandler) DeleteNodePoolLabel(ctx context.Context, vkeID, nodePoolID, nodePoolLabelID string) error {
465 uri := fmt.Sprintf("%s/%s/node-pools/%s/labels/%s", vkePath, vkeID, nodePoolID, nodePoolLabelID)
466
467 req, err := k.client.NewRequest(ctx, http.MethodDelete, uri, nil)
468 if err != nil {
469 return err
470 }
471
472 _, err = k.client.DoWithContext(ctx, req, nil)
473 return err
474 }
475
476 // ListNodePoolTaints retrieves a list of taints from a node pool
477 func (k *KubernetesHandler) ListNodePoolTaints(ctx context.Context, vkeID, nodePoolID string) ([]NodePoolTaint, *http.Response, error) {
478 uri := fmt.Sprintf("%s/%s/node-pools/%s/taints", vkePath, vkeID, nodePoolID)
479
480 req, err := k.client.NewRequest(ctx, http.MethodGet, uri, nil)
481 if err != nil {
482 return nil, nil, err
483 }
484
485 taints := new(vkeNodePoolTaintsBase)
486 resp, err := k.client.DoWithContext(ctx, req, taints)
487 if err != nil {
488 return nil, resp, err
489 }
490
491 return taints.Taints, resp, nil
492 }
493
494 // CreateNodePoolTaint creates a taint on a node pool
495 func (k *KubernetesHandler) CreateNodePoolTaint(ctx context.Context, vkeID, nodePoolID string, nodePoolTaintReq *NodePoolTaintReq) (*NodePoolTaint, *http.Response, error) { //nolint:lll,dupl
496 uri := fmt.Sprintf("%s/%s/node-pools/%s/taints", vkePath, vkeID, nodePoolID)
497
498 req, err := k.client.NewRequest(ctx, http.MethodPost, uri, nodePoolTaintReq)
499 if err != nil {
500 return nil, nil, err
501 }
502
503 taint := new(vkeNodePoolTaintBase)
504 resp, err := k.client.DoWithContext(ctx, req, taint)
505 if err != nil {
506 return nil, resp, err
507 }
508
509 return taint.Taint, resp, nil
510 }
511
512 // GetNodePoolTaint retrieves a taint from a node pool
513 func (k *KubernetesHandler) GetNodePoolTaint(ctx context.Context, vkeID, nodePoolID, nodePoolTaintID string) (*NodePoolTaint, *http.Response, error) { //nolint:lll
514 uri := fmt.Sprintf("%s/%s/node-pools/%s/taints/%s", vkePath, vkeID, nodePoolID, nodePoolTaintID)
515 req, err := k.client.NewRequest(ctx, http.MethodGet, uri, nil)
516 if err != nil {
517 return nil, nil, err
518 }
519
520 taint := new(vkeNodePoolTaintBase)
521 resp, err := k.client.DoWithContext(ctx, req, taint)
522 if err != nil {
523 return nil, resp, err
524 }
525
526 return taint.Taint, resp, nil
527 }
528
529 // DeleteNodePoolTaint deletes a taint on a node pool
530 func (k *KubernetesHandler) DeleteNodePoolTaint(ctx context.Context, vkeID, nodePoolID, nodePoolTaintID string) error {
531 uri := fmt.Sprintf("%s/%s/node-pools/%s/taints/%s", vkePath, vkeID, nodePoolID, nodePoolTaintID)
532
533 req, err := k.client.NewRequest(ctx, http.MethodDelete, uri, nil)
534 if err != nil {
535 return err
536 }
537
538 _, err = k.client.DoWithContext(ctx, req, nil)
539 return err
540 }
541
542 // ListWorkerNodes retrieves a list of all worker nodes for a given node pool
543 func (k *KubernetesHandler) ListWorkerNodes(ctx context.Context, vkeID, nodePoolID string, options *ListOptions) ([]Node, *Meta, *http.Response, error) { //nolint:lll,dupl
544 uri := fmt.Sprintf("%s/%s/node-pools/%s/nodes", vkePath, vkeID, nodePoolID)
545
546 req, err := k.client.NewRequest(ctx, http.MethodGet, uri, nil)
547 if err != nil {
548 return nil, nil, nil, err
549 }
550
551 newValues, err := query.Values(options)
552 if err != nil {
553 return nil, nil, nil, err
554 }
555
556 req.URL.RawQuery = newValues.Encode()
557
558 nodes := new(vkeWorkerNodesBase)
559 resp, err := k.client.DoWithContext(ctx, req, &nodes)
560 if err != nil {
561 return nil, nil, resp, err
562 }
563
564 return nodes.WorkerNodes, nodes.Meta, resp, nil
565 }
566
567 // DeleteNodePoolInstance will remove a specified node from a nodepool
568 func (k *KubernetesHandler) DeleteNodePoolInstance(ctx context.Context, vkeID, nodePoolID, nodeID string) error {
569 req, err := k.client.NewRequest(
570 ctx,
571 http.MethodDelete,
572 fmt.Sprintf("%s/%s/node-pools/%s/nodes/%s", vkePath, vkeID, nodePoolID, nodeID),
573 nil,
574 )
575 if err != nil {
576 return err
577 }
578
579 _, err = k.client.DoWithContext(ctx, req, nil)
580 return err
581 }
582
583 // RecycleNodePoolInstance will recycle (destroy + redeploy) a given node on a nodepool
584 func (k *KubernetesHandler) RecycleNodePoolInstance(ctx context.Context, vkeID, nodePoolID, nodeID string) error {
585 req, err := k.client.NewRequest(
586 ctx,
587 http.MethodPost,
588 fmt.Sprintf("%s/%s/node-pools/%s/nodes/%s/recycle", vkePath, vkeID, nodePoolID, nodeID),
589 nil,
590 )
591 if err != nil {
592 return err
593 }
594
595 _, err = k.client.DoWithContext(ctx, req, nil)
596 return err
597 }
598
599 // GetKubeConfig returns the kubeconfig for the specified VKE cluster
600 func (k *KubernetesHandler) GetKubeConfig(ctx context.Context, vkeID string) (*KubeConfig, *http.Response, error) {
601 req, err := k.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/config", vkePath, vkeID), nil)
602 if err != nil {
603 return nil, nil, err
604 }
605
606 kc := new(KubeConfig)
607 resp, err := k.client.DoWithContext(ctx, req, &kc)
608 if err != nil {
609 return nil, resp, err
610 }
611
612 return kc, resp, nil
613 }
614
615 // GetVersions returns the supported kubernetes versions
616 func (k *KubernetesHandler) GetVersions(ctx context.Context) (*Versions, *http.Response, error) {
617 uri := "/v2/kubernetes/versions"
618 req, err := k.client.NewRequest(ctx, http.MethodGet, uri, nil)
619 if err != nil {
620 return nil, nil, err
621 }
622
623 versions := new(Versions)
624 resp, err := k.client.DoWithContext(ctx, req, &versions)
625 if err != nil {
626 return nil, resp, err
627 }
628
629 return versions, resp, nil
630 }
631
632 // GetUpgrades returns all version a VKE cluster can upgrade to
633 func (k *KubernetesHandler) GetUpgrades(ctx context.Context, vkeID string) ([]string, *http.Response, error) {
634 req, err := k.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/available-upgrades", vkePath, vkeID), nil)
635 if err != nil {
636 return nil, nil, err
637 }
638
639 upgrades := new(availableUpgrades)
640 resp, err := k.client.DoWithContext(ctx, req, &upgrades)
641 if err != nil {
642 return nil, resp, err
643 }
644
645 return upgrades.AvailableUpgrades, resp, nil
646 }
647
648 // Upgrade beings a VKE cluster upgrade
649 func (k *KubernetesHandler) Upgrade(ctx context.Context, vkeID string, body *ClusterUpgradeReq) error {
650 req, err := k.client.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/%s/upgrades", vkePath, vkeID), body)
651 if err != nil {
652 return err
653 }
654
655 _, err = k.client.DoWithContext(ctx, req, nil)
656 return err
657 }
658