Skip to content

Commit c1a08c4

Browse files
authored
feat(k8s): rework kubeconfig handling (#4137)
1 parent 2fe8430 commit c1a08c4

File tree

37 files changed

+22717
-7005
lines changed

37 files changed

+22717
-7005
lines changed

cmd/scw/testdata/test-all-usage-k8s-kubeconfig-get-usage.golden

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ EXAMPLES:
99
Get the kubeconfig for a given cluster
1010
scw k8s kubeconfig get 11111111-1111-1111-1111-111111111111
1111

12+
Get the kubeconfig for a given cluster by copying current secret_key to it
13+
scw k8s kubeconfig get 11111111-1111-1111-1111-111111111111 auth-method=copy-cli-token
14+
15+
Get the kubeconfig for a given cluster and use legacy authentication
16+
scw k8s kubeconfig get 11111111-1111-1111-1111-111111111111 auth-method=legacy
17+
1218
ARGS:
13-
cluster-id Cluster ID from which to retrieve the kubeconfig
14-
[region=fr-par] Region to target. If none is passed will use default region from the config
19+
cluster-id Cluster ID from which to retrieve the kubeconfig
20+
[auth-method=cli] Which method to use to authenticate using kubelet (cli | copy-cli-token | legacy)
21+
[region=fr-par] Region to target. If none is passed will use default region from the config
1522

1623
FLAGS:
1724
-h, --help help for get

cmd/scw/testdata/test-all-usage-k8s-kubeconfig-install-usage.golden

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ EXAMPLES:
1010
Install the kubeconfig for a given cluster and using the new context
1111
scw k8s kubeconfig install 11111111-1111-1111-1111-111111111111
1212

13+
Get the kubeconfig for a given cluster by copying current secret_key to it
14+
scw k8s kubeconfig install 11111111-1111-1111-1111-111111111111 auth-method=copy-cli-token
15+
16+
Get the kubeconfig for a given cluster and use legacy authentication
17+
scw k8s kubeconfig install 11111111-1111-1111-1111-111111111111 auth-method=legacy
18+
1319
ARGS:
1420
cluster-id Cluster ID from which to retrieve the kubeconfig
21+
[auth-method=cli] Which method to use to authenticate using kubelet (cli | copy-cli-token | legacy)
1522
[keep-current-context] Whether or not to keep the current kubeconfig context unmodified
1623
[region=fr-par] Region to target. If none is passed will use default region from the config
1724

docs/commands/k8s.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ scw k8s kubeconfig get <cluster-id ...> [arg=value ...]
640640
| Name | | Description |
641641
|------|---|-------------|
642642
| cluster-id | Required | Cluster ID from which to retrieve the kubeconfig |
643+
| auth-method | Default: `cli`<br />One of: `cli`, `copy-cli-token`, `legacy` | Which method to use to authenticate using kubelet |
643644
| region | Default: `fr-par` | Region to target. If none is passed will use default region from the config |
644645

645646

@@ -651,6 +652,16 @@ Get the kubeconfig for a given cluster
651652
scw k8s kubeconfig get 11111111-1111-1111-1111-111111111111
652653
```
653654

655+
Get the kubeconfig for a given cluster by copying current secret_key to it
656+
```
657+
scw k8s kubeconfig get 11111111-1111-1111-1111-111111111111 auth-method=copy-cli-token
658+
```
659+
660+
Get the kubeconfig for a given cluster and use legacy authentication
661+
```
662+
scw k8s kubeconfig get 11111111-1111-1111-1111-111111111111 auth-method=legacy
663+
```
664+
654665

655666

656667

@@ -671,6 +682,7 @@ scw k8s kubeconfig install <cluster-id ...> [arg=value ...]
671682
| Name | | Description |
672683
|------|---|-------------|
673684
| cluster-id | Required | Cluster ID from which to retrieve the kubeconfig |
685+
| auth-method | Default: `cli`<br />One of: `cli`, `copy-cli-token`, `legacy` | Which method to use to authenticate using kubelet |
674686
| keep-current-context | | Whether or not to keep the current kubeconfig context unmodified |
675687
| region | Default: `fr-par` | Region to target. If none is passed will use default region from the config |
676688

@@ -683,6 +695,16 @@ Install the kubeconfig for a given cluster and using the new context
683695
scw k8s kubeconfig install 11111111-1111-1111-1111-111111111111
684696
```
685697

698+
Get the kubeconfig for a given cluster by copying current secret_key to it
699+
```
700+
scw k8s kubeconfig install 11111111-1111-1111-1111-111111111111 auth-method=copy-cli-token
701+
```
702+
703+
Get the kubeconfig for a given cluster and use legacy authentication
704+
```
705+
scw k8s kubeconfig install 11111111-1111-1111-1111-111111111111 auth-method=legacy
706+
```
707+
686708

687709

688710

internal/namespaces/k8s/v1/custom.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package k8s
22

33
import (
4+
"context"
5+
"errors"
6+
47
"github.com/scaleway/scaleway-cli/v2/core"
58
"github.com/scaleway/scaleway-cli/v2/core/human"
69
k8s "github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
711
)
812

913
// GetCommands returns cluster commands.
@@ -60,3 +64,25 @@ func GetCommands() *core.Commands {
6064

6165
return cmds
6266
}
67+
68+
func extractSecretKey(ctx context.Context) (string, error) {
69+
config, _ := scw.LoadConfigFromPath(core.ExtractConfigPath(ctx))
70+
profileName := core.ExtractProfileName(ctx)
71+
72+
switch {
73+
// Environment variable check
74+
case core.ExtractEnv(ctx, scw.ScwSecretKeyEnv) != "":
75+
return core.ExtractEnv(ctx, scw.ScwSecretKeyEnv), nil
76+
// There is no config file
77+
case config == nil:
78+
return "", errors.New("config not provided")
79+
// Config file with profile name
80+
case config.Profiles[profileName] != nil && config.Profiles[profileName].SecretKey != nil:
81+
return *config.Profiles[profileName].SecretKey, nil
82+
// Default config
83+
case config.SecretKey != nil:
84+
return *config.SecretKey, nil
85+
}
86+
87+
return "", errors.New("unable to find secret key")
88+
}

internal/namespaces/k8s/v1/custom_cluster_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@ import (
1010
func Test_GetCluster(t *testing.T) {
1111
t.Run("Simple", core.Test(&core.TestConfig{
1212
Commands: k8s.GetCommands(),
13-
BeforeFunc: createCluster("get-cluster", "Cluster", kapsuleVersion, 1, "DEV1-M"),
13+
BeforeFunc: createCluster("get-cluster", 1, "DEV1-M"),
1414
Cmd: "scw k8s cluster get {{ .Cluster.ID }}",
1515
Check: core.TestCheckCombine(
1616
core.TestCheckGolden(),
1717
core.TestCheckExitCode(0),
1818
),
19-
AfterFunc: deleteCluster("Cluster"),
19+
AfterFunc: deleteCluster(),
2020
}))
2121
}
2222

2323
func Test_WaitCluster(t *testing.T) {
2424
t.Run("wait for pools", core.Test(&core.TestConfig{
2525
Commands: k8s.GetCommands(),
26-
BeforeFunc: createCluster("wait-cluster", "Cluster", kapsuleVersion, 1, "GP1-XS"),
26+
BeforeFunc: createCluster("wait-cluster", 1, "GP1-XS"),
2727
Cmd: "scw k8s cluster wait {{ .Cluster.ID }} wait-for-pools=true",
2828
Check: core.TestCheckCombine(
2929
core.TestCheckGolden(),
3030
core.TestCheckExitCode(0),
3131
),
32-
AfterFunc: deleteCluster("Cluster"),
32+
AfterFunc: deleteCluster(),
3333
}))
3434
}

internal/namespaces/k8s/v1/custom_execcredentials.go

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@ package k8s
33
import (
44
"context"
55
"encoding/json"
6-
"errors"
7-
"fmt"
86
"reflect"
97

108
"github.com/scaleway/scaleway-cli/v2/core"
11-
"github.com/scaleway/scaleway-sdk-go/scw"
129
"github.com/scaleway/scaleway-sdk-go/validation"
1310
)
1411

@@ -28,39 +25,20 @@ func k8sExecCredentialCommand() *core.Command {
2825
}
2926

3027
func k8sExecCredentialRun(ctx context.Context, _ any) (i any, e error) {
31-
config, _ := scw.LoadConfigFromPath(core.ExtractConfigPath(ctx))
32-
profileName := core.ExtractProfileName(ctx)
33-
34-
var token string
35-
switch {
36-
// Environment variable check
37-
case core.ExtractEnv(ctx, scw.ScwSecretKeyEnv) != "":
38-
token = core.ExtractEnv(ctx, scw.ScwSecretKeyEnv)
39-
// There is no config file
40-
case config == nil:
41-
return nil, errors.New("config not provided")
42-
// Config file with profile name
43-
case config.Profiles[profileName] != nil && config.Profiles[profileName].SecretKey != nil:
44-
token = *config.Profiles[profileName].SecretKey
45-
// Default config
46-
case config.SecretKey != nil:
47-
token = *config.SecretKey
48-
default:
49-
return nil, errors.New("unable to find secret key")
28+
secretKey, err := extractSecretKey(ctx)
29+
if err != nil {
30+
return nil, err
5031
}
5132

52-
if !validation.IsSecretKey(token) {
53-
return nil, fmt.Errorf(
54-
"invalid secret key format '%s', expected a UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
55-
token,
56-
)
33+
if !validation.IsSecretKey(secretKey) {
34+
return nil, core.InvalidSecretKeyError(secretKey)
5735
}
5836

5937
execCreds := ExecCredential{
6038
APIVersion: "client.authentication.k8s.io/v1",
6139
Kind: "ExecCredential",
6240
Status: &ExecCredentialStatus{
63-
Token: token,
41+
Token: secretKey,
6442
},
6543
}
6644
response, err := json.MarshalIndent(execCreds, "", " ")

internal/namespaces/k8s/v1/custom_execcredentials_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ const (
2020
)
2121

2222
func Test_ExecCredential(t *testing.T) {
23-
// expect to return default secret_key
23+
////
24+
// Simple expect to return current secret_key
25+
////
2426
t.Run("simple", core.Test(&core.TestConfig{
2527
Commands: k8s.GetCommands(),
2628
TmpHomeDir: true,
@@ -37,7 +39,9 @@ func Test_ExecCredential(t *testing.T) {
3739
),
3840
}))
3941

42+
////
4043
// expect to return 66666666-6666-6666-6666-666666666666
44+
////
4145
t.Run("with scw_secret_key env", core.Test(&core.TestConfig{
4246
Commands: k8s.GetCommands(),
4347
TmpHomeDir: true,
@@ -53,7 +57,9 @@ func Test_ExecCredential(t *testing.T) {
5357
),
5458
}))
5559

60+
////
5661
// expect to return p2 secret_key
62+
////
5763
t.Run("with profile env", core.Test(&core.TestConfig{
5864
Commands: k8s.GetCommands(),
5965
TmpHomeDir: true,
@@ -71,7 +77,9 @@ func Test_ExecCredential(t *testing.T) {
7177
),
7278
}))
7379

80+
////
7481
// expect to return p3 secret_key
82+
////
7583
t.Run("with profile flag", core.Test(&core.TestConfig{
7684
Commands: k8s.GetCommands(),
7785
TmpHomeDir: true,
@@ -88,7 +96,9 @@ func Test_ExecCredential(t *testing.T) {
8896
),
8997
}))
9098

99+
////
91100
// expect to return p3 secret_key
101+
////
92102
t.Run("with profile env and flag", core.Test(&core.TestConfig{
93103
Commands: k8s.GetCommands(),
94104
TmpHomeDir: true,
@@ -111,12 +121,16 @@ func beforeFuncCreateConfigFile(c *scw.Config) core.BeforeFunc {
111121
return func(ctx *core.BeforeFuncCtx) error {
112122
homeDir := ctx.OverrideEnv["HOME"]
113123
scwDir := path.Join(homeDir, ".config", "scw")
114-
err := os.MkdirAll(scwDir, 0o0755)
115-
if err != nil {
124+
if err := os.MkdirAll(scwDir, 0o0755); err != nil {
125+
return err
126+
}
127+
128+
scwPath := path.Join(scwDir, "config.yaml")
129+
if err := c.SaveTo(scwPath); err != nil {
116130
return err
117131
}
118132

119-
return c.SaveTo(path.Join(scwDir, "config.yaml"))
133+
return nil
120134
}
121135
}
122136

0 commit comments

Comments
 (0)