Skip to content

Commit 1f4164b

Browse files
committed
select nodepool id when describe cluster attach scripts
Signed-off-by: Vacant2333 <vacant2333@gmail.com>
1 parent d88bf13 commit 1f4164b

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

pkg/providers/ack/ack.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"fmt"
2525
"net/http"
2626
"regexp"
27+
"sort"
2728
"strings"
2829
"sync"
2930

@@ -103,15 +104,71 @@ func (p *DefaultProvider) GetClusterCNI(_ context.Context) (string, error) {
103104
return p.clusterCNI, nil
104105
}
105106

107+
// Get the ID of the target nodepool id when DescribeClusterAttachScriptsRequest.
108+
// If there is no default nodepool, select the nodepool with the most HealthyNodes.
109+
//
110+
//nolint:gocyclo
111+
func (p *DefaultProvider) getTargetNodePoolID(ctx context.Context) (*string, error) {
112+
resp, err := p.ackClient.DescribeClusterNodePools(tea.String(p.clusterID), &ackclient.DescribeClusterNodePoolsRequest{})
113+
if err != nil {
114+
log.FromContext(ctx).Error(err, "Failed to describe cluster nodepools")
115+
return nil, err
116+
}
117+
if resp == nil || resp.Body == nil || resp.Body.Nodepools == nil {
118+
return nil, fmt.Errorf("empty describe cluster nodepools response")
119+
}
120+
if len(resp.Body.Nodepools) == 0 {
121+
return nil, fmt.Errorf("no nodepool found")
122+
}
123+
124+
nodepools := resp.Body.Nodepools
125+
sort.Slice(nodepools, func(i, j int) bool {
126+
if nodepools[i].NodepoolInfo == nil || nodepools[j].NodepoolInfo == nil {
127+
return false
128+
}
129+
130+
if nodepools[i].NodepoolInfo.IsDefault != nil && nodepools[j].NodepoolInfo.IsDefault != nil {
131+
if *nodepools[i].NodepoolInfo.IsDefault && !*nodepools[j].NodepoolInfo.IsDefault {
132+
return true
133+
}
134+
if !*nodepools[i].NodepoolInfo.IsDefault && *nodepools[j].NodepoolInfo.IsDefault {
135+
return false
136+
}
137+
}
138+
139+
if nodepools[i].Status == nil || nodepools[j].Status == nil || nodepools[i].Status.HealthyNodes == nil || nodepools[j].Status.HealthyNodes == nil {
140+
return false
141+
}
142+
return *nodepools[i].Status.HealthyNodes > *nodepools[j].Status.HealthyNodes
143+
})
144+
145+
targetNodepool := nodepools[0]
146+
if targetNodepool.NodepoolInfo == nil {
147+
return nil, fmt.Errorf("target describe cluster nodepool is empty")
148+
}
149+
return targetNodepool.NodepoolInfo.NodepoolId, nil
150+
}
151+
106152
func (p *DefaultProvider) GetNodeRegisterScript(ctx context.Context,
107153
labels map[string]string,
108154
kubeletCfg *v1alpha1.KubeletConfiguration) (string, error) {
109155
if cachedScript, ok := p.cache.Get(p.clusterID); ok {
110156
return p.resolveUserData(cachedScript.(string), labels, kubeletCfg), nil
111157
}
112158

159+
nodepoolID, err := p.getTargetNodePoolID(ctx)
160+
if err != nil {
161+
// Don't return here, we can process when there is no default cluster id.
162+
// We need to try to obtain a usable nodepool ID in order to get the cluster attach scripts.
163+
// One known scenario is on an ACK cluster with version 1.24, where the user deleted the default nodepool and
164+
// created a nodepool with a containerd runtime. The DescribeClusterAttachScriptsRequest api will use the
165+
// CRI configuration of the deleted default nodepool, which might be using the Docker runtime.
166+
// This could result in nodes failing to register to the new cluster.
167+
log.FromContext(ctx).Error(err, "Failed to get default nodepool id")
168+
}
113169
reqPara := &ackclient.DescribeClusterAttachScriptsRequest{
114170
KeepInstanceName: tea.Bool(true),
171+
NodepoolId: nodepoolID,
115172
}
116173
resp, err := p.ackClient.DescribeClusterAttachScripts(tea.String(p.clusterID), reqPara)
117174
if err != nil {

0 commit comments

Comments
 (0)