Skip to content

Commit 02bd176

Browse files
ConnorJC3cPu1
andauthoredMay 24, 2022
Detect kubectl version during kubeconfig generation and avoid known non-working configurations (#5288)
* Detect kubectl version during kubeconfig generation and avoid known non-working configurations (#5257) * Update kubectl check to use JSON output instead of short output * Update pkg/utils/kubeconfig/kubeconfig.go with PR suggestion Co-authored-by: Chetan Patwal <[email protected]> Co-authored-by: Chetan Patwal <[email protected]>
1 parent bd5e659 commit 02bd176

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed
 

‎pkg/utils/kubeconfig/kubeconfig.go

+48
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,19 @@ func AppendAuthenticator(config *clientcmdapi.Config, clusterMeta *api.ClusterMe
189189
args = append(args, "--region", clusterMeta.Region)
190190
}
191191
}
192+
// If the alpha API version is selected, check the kubectl version
193+
// If kubectl 1.24.0 or above is detected, override with the beta API version
194+
// kubectl 1.24.0 removes the alpha API version, so it will never work
195+
// Therefore as a best effort try the beta version even if it might not work
196+
if execConfig.APIVersion == alphaAPIVersion {
197+
if kubectlVersion := getKubectlVersion(); kubectlVersion != "" {
198+
// Silently ignore errors because kubectl is not required to run eksctl
199+
compareVersions, err := utils.CompareVersions(kubectlVersion, "1.24.0")
200+
if err == nil && compareVersions >= 0 {
201+
execConfig.APIVersion = betaAPIVersion
202+
}
203+
}
204+
}
192205
if roleARN != "" {
193206
args = append(args, roleARNFlag, roleARN)
194207
}
@@ -238,6 +251,41 @@ func getAWSIAMAuthenticatorVersion() (string, error) {
238251
return parsedVersion.Version, nil
239252
}
240253

254+
/* KubectlVersionFormat is the format used by kubectl version --format=json, example output:
255+
{
256+
"clientVersion": {
257+
"major": "1",
258+
"minor": "23",
259+
"gitVersion": "v1.23.6",
260+
"gitCommit": "ad3338546da947756e8a88aa6822e9c11e7eac22",
261+
"gitTreeState": "archive",
262+
"buildDate": "2022-04-29T06:39:16Z",
263+
"goVersion": "go1.18.1",
264+
"compiler": "gc",
265+
"platform": "linux/amd64"
266+
}
267+
} */
268+
type KubectlVersionData struct {
269+
Version string `json:"gitVersion"`
270+
}
271+
272+
type KubectlVersionFormat struct {
273+
ClientVersion KubectlVersionData `json:"clientVersion"`
274+
}
275+
276+
func getKubectlVersion() string {
277+
cmd := execCommand("kubectl", "version", "--client", "--output=json")
278+
output, err := cmd.Output()
279+
if err != nil {
280+
return ""
281+
}
282+
var parsedVersion KubectlVersionFormat
283+
if err := json.Unmarshal(output, &parsedVersion); err != nil {
284+
return ""
285+
}
286+
return strings.TrimLeft(parsedVersion.ClientVersion.Version, "v")
287+
}
288+
241289
func lockFileName(filePath string) string {
242290
return filePath + ".eksctl.lock"
243291
}

‎pkg/utils/kubeconfig/kubeconfig_test.go

+23-6
Original file line numberDiff line numberDiff line change
@@ -373,42 +373,59 @@ var _ = Describe("Kubeconfig", func() {
373373
})
374374
It("writes the right api version if aws-iam-authenticator version is below 0.5.3", func() {
375375
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
376-
return exec.Command(filepath.Join("testdata", "aws-iam-authenticator"), `{"Version":"0.5.1","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
376+
return exec.Command(filepath.Join("testdata", "fake-version"), `{"Version":"0.5.1","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
377377
})
378378
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
379379
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1alpha1"))
380380
})
381381
It("writes the right api version if aws-iam-authenticator version is above 0.5.3", func() {
382382
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
383-
return exec.Command(filepath.Join("testdata", "aws-iam-authenticator"), `{"Version":"0.5.5","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
383+
return exec.Command(filepath.Join("testdata", "fake-version"), `{"Version":"0.5.5","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
384384
})
385385
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
386386
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1beta1"))
387387
})
388388
It("writes the right api version if aws-iam-authenticator version equals 0.5.3", func() {
389389
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
390-
return exec.Command(filepath.Join("testdata", "aws-iam-authenticator"), `{"Version":"0.5.3","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
390+
return exec.Command(filepath.Join("testdata", "fake-version"), `{"Version":"0.5.3","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
391391
})
392392
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
393393
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1beta1"))
394394
})
395395
It("defaults to alpha1 if we fail to detect aws-iam-authenticator version", func() {
396396
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
397-
return exec.Command(filepath.Join("testdata", "aws-iam-authenticator"), "fail")
397+
return exec.Command(filepath.Join("testdata", "fake-version"), "fail")
398398
})
399399
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
400400
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1alpha1"))
401401
})
402402
It("defaults to alpha1 if we fail to parse the output", func() {
403403
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
404-
return exec.Command(filepath.Join("testdata", "aws-iam-authenticator"), "not-json-output")
404+
return exec.Command(filepath.Join("testdata", "fake-version"), "not-json-output")
405405
})
406406
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
407407
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1alpha1"))
408408
})
409409
It("defaults to alpha1 if we can't parse the version because it's a dev version", func() {
410410
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
411-
return exec.Command(filepath.Join("testdata", "aws-iam-authenticator"), `{"Version":"git-85e50980","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
411+
return exec.Command(filepath.Join("testdata", "fake-version"), `{"Version":"git-85e50980","Commit":"85e50980d9d916ae95882176c18f14ae145f916f"}`)
412+
})
413+
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
414+
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1alpha1"))
415+
})
416+
It("defaults to beta1 if we detect kubectl 1.24.0 or above", func() {
417+
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
418+
return exec.Command(filepath.Join("testdata", "fake-version"), `{"clientVersion": {"gitVersion": "v1.24.0"}}`)
419+
})
420+
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSEKSAuthenticator, "", "")
421+
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1beta1"))
422+
})
423+
It("doesn't default to beta1 if we detect kubectl 1.23.0 or below", func() {
424+
kubeconfig.SetExecCommand(func(name string, arg ...string) *exec.Cmd {
425+
if name == "kubectl" {
426+
return exec.Command(filepath.Join("testdata", "fake-version"), `{"clientVersion": {"gitVersion": "v1.23.6"}}`)
427+
}
428+
return exec.Command(filepath.Join("testdata", "fake-version"), "fail")
412429
})
413430
kubeconfig.AppendAuthenticator(config, clusterMeta, kubeconfig.AWSIAMAuthenticator, "", "")
414431
Expect(config.AuthInfos["test"].Exec.APIVersion).To(Equal("client.authentication.k8s.io/v1alpha1"))

0 commit comments

Comments
 (0)
Please sign in to comment.