Skip to content

Commit 192af14

Browse files
authored
fix(kapsule): allow getting kubeconfig with readonly permission (#5049)
1 parent c830f9f commit 192af14

24 files changed

+10537
-11877
lines changed

internal/namespaces/k8s/v1/custom_cluster_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ 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", 1, "DEV1-M"),
13+
BeforeFunc: createCluster("get-cluster", false),
1414
Cmd: "scw k8s cluster get {{ .Cluster.ID }}",
1515
Check: core.TestCheckCombine(
1616
core.TestCheckGolden(),
@@ -23,7 +23,7 @@ func Test_GetCluster(t *testing.T) {
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", 1, "GP1-XS"),
26+
BeforeFunc: createCluster("wait-cluster", false),
2727
Cmd: "scw k8s cluster wait {{ .Cluster.ID }} wait-for-pools=true",
2828
Check: core.TestCheckCombine(
2929
core.TestCheckGolden(),

internal/namespaces/k8s/v1/custom_kubeconfig_get.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ func k8sKubeconfigGetRun(ctx context.Context, argsI any) (i any, e error) {
7272
GetClusterKubeConfig(&k8s.GetClusterKubeConfigRequest{
7373
Region: request.Region,
7474
ClusterID: request.ClusterID,
75+
Redacted: scw.BoolPtr(
76+
request.AuthMethod != authMethodLegacy,
77+
), // put true after legacy deprecation
7578
})
7679
if err != nil {
7780
return nil, err

internal/namespaces/k8s/v1/custom_kubeconfig_get_test.go

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ func Test_GetKubeconfig(t *testing.T) {
1717
////
1818
// Simple use case
1919
////
20-
2120
t.Run("simple", core.Test(&core.TestConfig{
2221
Commands: k8s.GetCommands(),
23-
BeforeFunc: createClusterAndWaitAndKubeconfig(
24-
"get-kubeconfig-simple",
22+
BeforeFunc: core.BeforeFuncCombine(
23+
createCluster("get-kubeconfig-simple", true),
24+
fetchClusterKubeconfigMetadata(true),
2525
),
2626
Cmd: "scw k8s kubeconfig get {{ ." + clusterMetaKey + ".ID }}",
2727
OverrideEnv: map[string]string{
@@ -81,8 +81,9 @@ func Test_GetKubeconfig(t *testing.T) {
8181
////
8282
t.Run("with_flags", core.Test(&core.TestConfig{
8383
Commands: k8s.GetCommands(),
84-
BeforeFunc: createClusterAndWaitAndKubeconfig(
85-
"get-kubeconfig-with-flags",
84+
BeforeFunc: core.BeforeFuncCombine(
85+
createCluster("get-kubeconfig-with-flags", true),
86+
fetchClusterKubeconfigMetadata(true),
8687
),
8788
Cmd: "scw k8s --profile=default kubeconfig get {{ ." + clusterMetaKey + ".ID }}",
8889
OverrideEnv: map[string]string{
@@ -147,8 +148,9 @@ func Test_GetKubeconfig(t *testing.T) {
147148

148149
t.Run("with_envs", core.Test(&core.TestConfig{
149150
Commands: k8s.GetCommands(),
150-
BeforeFunc: createClusterAndWaitAndKubeconfig(
151-
"get-kubeconfig-with-envs",
151+
BeforeFunc: core.BeforeFuncCombine(
152+
createCluster("get-kubeconfig-with-envs", true),
153+
fetchClusterKubeconfigMetadata(true),
152154
),
153155
Cmd: "scw k8s kubeconfig get {{ ." + clusterMetaKey + ".ID }}",
154156
OverrideEnv: map[string]string{
@@ -212,8 +214,9 @@ func Test_GetKubeconfig(t *testing.T) {
212214
////
213215
t.Run("with_flags_and_envs", core.Test(&core.TestConfig{
214216
Commands: k8s.GetCommands(),
215-
BeforeFunc: createClusterAndWaitAndKubeconfig(
216-
"get-kubeconfig-with-flags-and-envs",
217+
BeforeFunc: core.BeforeFuncCombine(
218+
createCluster("get-kubeconfig-with-flags-and-envs", true),
219+
fetchClusterKubeconfigMetadata(true),
217220
),
218221
Cmd: "scw --profile=default k8s kubeconfig get {{ ." + clusterMetaKey + ".ID }}",
219222
OverrideEnv: map[string]string{
@@ -283,10 +286,12 @@ func Test_GetKubeconfig(t *testing.T) {
283286
t.Run("legacy", core.Test(&core.TestConfig{
284287
Commands: k8s.GetCommands(),
285288
Cmd: "scw k8s kubeconfig get {{ ." + clusterMetaKey + ".ID }} auth-method=legacy",
286-
BeforeFunc: createClusterAndWaitAndKubeconfig(
287-
"get-kubeconfig-legacy",
289+
BeforeFunc: core.BeforeFuncCombine(
290+
createCluster("get-kubeconfig-legacy", true),
291+
fetchClusterKubeconfigMetadata(false),
288292
),
289293
Check: core.TestCheckCombine(
294+
core.TestCheckGolden(),
290295
core.TestCheckExitCode(0),
291296
func(t *testing.T, ctx *core.CheckFuncCtx) {
292297
t.Helper()
@@ -304,8 +309,9 @@ func Test_GetKubeconfig(t *testing.T) {
304309
////
305310
t.Run("copy_cli_token", core.Test(&core.TestConfig{
306311
Commands: k8s.GetCommands(),
307-
BeforeFunc: createClusterAndWaitAndKubeconfig(
308-
"get-kubeconfig-copy-cli-token",
312+
BeforeFunc: core.BeforeFuncCombine(
313+
createCluster("get-kubeconfig-copy-cli-token", true),
314+
fetchClusterKubeconfigMetadata(true),
309315
),
310316
Cmd: "scw k8s kubeconfig get {{ ." + clusterMetaKey + ".ID }} auth-method=copy-cli-token",
311317
OverrideEnv: map[string]string{

internal/namespaces/k8s/v1/custom_kubeconfig_install.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ func k8sKubeconfigInstallRun(ctx context.Context, argsI any) (i any, e error) {
8686
GetClusterKubeConfig(&k8s.GetClusterKubeConfigRequest{
8787
Region: request.Region,
8888
ClusterID: request.ClusterID,
89+
Redacted: scw.BoolPtr(
90+
request.AuthMethod != authMethodLegacy,
91+
), // put true after legacy deprecation
8992
})
9093
if err != nil {
9194
return nil, err

internal/namespaces/k8s/v1/custom_kubeconfig_install_test.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ func Test_InstallKubeconfig(t *testing.T) {
4848
t.Run("simple", core.Test(&core.TestConfig{
4949
Commands: k8s.GetCommands(),
5050
TmpHomeDir: true,
51-
BeforeFunc: createClusterAndWaitAndKubeconfig(
52-
"install-kubeconfig-simple",
51+
BeforeFunc: core.BeforeFuncCombine(
52+
createCluster("install-kubeconfig-simple", true),
53+
fetchClusterKubeconfigMetadata(true),
5354
),
5455
Cmd: "scw k8s kubeconfig install {{ ." + clusterMetaKey + ".ID }}",
5556
Check: core.TestCheckCombine(
@@ -101,9 +102,10 @@ func Test_InstallKubeconfig(t *testing.T) {
101102
t.Run("merge", core.Test(&core.TestConfig{
102103
Commands: k8s.GetCommands(),
103104
TmpHomeDir: true,
104-
BeforeFunc: populateKubeconfigAndCreateCluster(
105-
[]byte(existingKubeconfig),
106-
"install-kubeconfig-merge",
105+
BeforeFunc: core.BeforeFuncCombine(
106+
writeKubeconfigFile([]byte(existingKubeconfig)),
107+
createCluster("install-kubeconfig-merge", true),
108+
fetchClusterKubeconfigMetadata(true),
107109
),
108110
Cmd: "scw k8s kubeconfig install {{ ." + clusterMetaKey + ".ID }}",
109111
Check: core.TestCheckCombine(
@@ -165,9 +167,10 @@ func Test_InstallKubeconfig(t *testing.T) {
165167
t.Run("merge-keep", core.Test(&core.TestConfig{
166168
Commands: k8s.GetCommands(),
167169
TmpHomeDir: true,
168-
BeforeFunc: populateKubeconfigAndCreateCluster(
169-
[]byte(existingKubeconfig),
170-
"install-kubeconfig-merge-keep",
170+
BeforeFunc: core.BeforeFuncCombine(
171+
writeKubeconfigFile([]byte(existingKubeconfig)),
172+
createCluster("install-kubeconfig-merge-keep", true),
173+
fetchClusterKubeconfigMetadata(true),
171174
),
172175
Cmd: "scw k8s kubeconfig install {{ ." + clusterMetaKey + ".ID }} keep-current-context=true",
173176
Check: core.TestCheckCombine(
@@ -241,9 +244,10 @@ func Test_InstallKubeconfig(t *testing.T) {
241244
testConfig := &core.TestConfig{
242245
Commands: k8s.GetCommands(),
243246
TmpHomeDir: true,
244-
BeforeFunc: populateKubeconfigAndCreateCluster(
245-
[]byte(existingKubeconfig),
246-
"install-kubeconfig-merge-kubeconfig",
247+
BeforeFunc: core.BeforeFuncCombine(
248+
writeKubeconfigFile([]byte(existingKubeconfig)),
249+
createCluster("install-kubeconfig-merge-kubeconfig", true),
250+
fetchClusterKubeconfigMetadata(true),
247251
),
248252
Cmd: "scw k8s kubeconfig install {{ ." + clusterMetaKey + ".ID }}",
249253
Check: core.TestCheckCombine(

internal/namespaces/k8s/v1/custom_kubeconfig_uninstall_test.go

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package k8s_test
22

33
import (
4-
"errors"
54
"os"
65
"path"
76
"strings"
@@ -203,24 +202,11 @@ func Test_UninstallKubeconfig(t *testing.T) {
203202
t.Run("uninstall_real_merge", core.Test(&core.TestConfig{
204203
Commands: k8s.GetCommands(),
205204
TmpHomeDir: true,
206-
BeforeFunc: func(ctx *core.BeforeFuncCtx) error {
207-
bfunc := populateKubeconfigAndCreateCluster(
208-
[]byte(uninstallKubeconfig),
209-
"uninstall-kubeconfig-merge",
210-
)
211-
if err := bfunc(ctx); err != nil {
212-
return err
213-
}
214-
215-
cluster := ctx.Meta[clusterMetaKey].(*k8sSDK.Cluster)
216-
cmd := "scw k8s kubeconfig install " + cluster.ID
217-
installOut := ctx.ExecuteCmd(strings.Split(cmd, " "))
218-
if !strings.Contains(installOut.(string), "successfully written") {
219-
return errors.New("kubeconfig install failed")
220-
}
221-
222-
return nil
223-
},
205+
BeforeFunc: core.BeforeFuncCombine(
206+
createCluster("uninstall-kubeconfig-merge", true),
207+
fetchClusterKubeconfigMetadata(true),
208+
cliInstallKubeconfig(),
209+
),
224210
Cmd: "scw k8s kubeconfig uninstall {{ ." + clusterMetaKey + ".ID }}",
225211
Check: core.TestCheckCombine(
226212
// no golden tests since it's os specific

internal/namespaces/k8s/v1/helpers_test.go

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package k8s_test
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"path"
@@ -10,6 +11,7 @@ import (
1011
"github.com/scaleway/scaleway-cli/v2/core"
1112
go_api "github.com/scaleway/scaleway-cli/v2/internal/namespaces/k8s/v1/types"
1213
k8s "github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
14+
"github.com/scaleway/scaleway-sdk-go/scw"
1315
)
1416

1517
const (
@@ -26,40 +28,35 @@ const (
2628
// register it in the context Meta at metaKey.
2729
func createCluster(
2830
clusterNameSuffix string,
29-
poolSize int,
30-
nodeType string,
31+
wait bool,
3132
) core.BeforeFunc {
33+
format := "scw k8s cluster create name=cli-test-%s version=%s cni=cilium pools.0.node-type=DEV1-M pools.0.size=1 pools.0.name=default"
34+
if wait {
35+
format += " --wait"
36+
}
37+
3238
return core.ExecStoreBeforeCmd(
3339
clusterMetaKey,
3440
fmt.Sprintf(
35-
"scw k8s cluster create name=cli-test-%s version=%s cni=cilium pools.0.node-type=%s pools.0.size=%d pools.0.name=default",
41+
format,
3642
clusterNameSuffix,
3743
kapsuleVersion,
38-
nodeType,
39-
poolSize,
4044
),
4145
)
4246
}
4347

44-
// createClusterAndWaitAndKubeconfig creates a basic cluster with 1 dev1-m as node, the given version and
45-
// register it in the context Meta at metaKey.
46-
func createClusterAndWaitAndKubeconfig(
47-
clusterNameSuffix string,
48+
// fetchClusterKubeconfigMetadata fetch kubeconfig of previously created cluster.
49+
func fetchClusterKubeconfigMetadata(
50+
redacted bool,
4851
) core.BeforeFunc {
4952
return func(ctx *core.BeforeFuncCtx) error {
50-
cmd := fmt.Sprintf(
51-
"scw k8s cluster create name=cli-test-%s version=%s cni=cilium pools.0.node-type=DEV1-M pools.0.size=1 pools.0.name=default --wait",
52-
clusterNameSuffix,
53-
kapsuleVersion,
54-
)
55-
res := ctx.ExecuteCmd(strings.Split(cmd, " "))
56-
cluster := res.(*k8s.Cluster)
57-
ctx.Meta[clusterMetaKey] = cluster
53+
cluster := ctx.Meta[clusterMetaKey].(*k8s.Cluster)
5854

5955
apiKubeconfig, err := k8s.NewAPI(ctx.Client).
6056
GetClusterKubeConfig(&k8s.GetClusterKubeConfigRequest{
6157
Region: cluster.Region,
6258
ClusterID: cluster.ID,
59+
Redacted: scw.BoolPtr(redacted),
6360
})
6461
if err != nil {
6562
return err
@@ -75,25 +72,28 @@ func createClusterAndWaitAndKubeconfig(
7572
}
7673
}
7774

78-
func populateKubeconfigAndCreateCluster(
79-
kubeconfigRaw []byte,
80-
clusterNameSuffix string,
81-
) core.BeforeFunc {
75+
func writeKubeconfigFile(kubeconfigRaw []byte) core.BeforeFunc {
8276
return func(ctx *core.BeforeFuncCtx) error {
8377
// Populate $HOME/.kube/config with existing data
8478
kubeconfigPath := path.Join(ctx.Meta["HOME"].(string), ".kube", "config")
8579
if err := os.MkdirAll(path.Dir(kubeconfigPath), 0o755); err != nil {
8680
return err
8781
}
8882

89-
if err := os.WriteFile(kubeconfigPath, kubeconfigRaw, 0o600); err != nil {
90-
return err
83+
return os.WriteFile(kubeconfigPath, kubeconfigRaw, 0o600)
84+
}
85+
}
86+
87+
func cliInstallKubeconfig() core.BeforeFunc {
88+
return func(ctx *core.BeforeFuncCtx) error {
89+
cluster := ctx.Meta[clusterMetaKey].(*k8s.Cluster)
90+
cmd := "scw k8s kubeconfig install " + cluster.ID
91+
installOut := ctx.ExecuteCmd(strings.Split(cmd, " "))
92+
if !strings.Contains(installOut.(string), "successfully written") {
93+
return errors.New("kubeconfig install failed")
9194
}
9295

93-
// Then create a cluster
94-
return createClusterAndWaitAndKubeconfig(
95-
clusterNameSuffix,
96-
)(ctx)
96+
return nil
9797
}
9898
}
9999

0 commit comments

Comments
 (0)