Skip to content

Commit 3473f60

Browse files
committed
feat: ske kubeconfig create merge kubeconfig into the default kubeconfig file
Signed-off-by: Javier Vela <fjvela@gmail.com>
1 parent a3a0754 commit 3473f60

File tree

4 files changed

+194
-25
lines changed

4 files changed

+194
-25
lines changed

docs/stackit_ske_kubeconfig_create.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
## stackit ske kubeconfig create
22

3-
Creates a kubeconfig for an SKE cluster
3+
Updates the kubeconfig setup for an SKE cluster.
44

55
### Synopsis
66

7-
Creates a kubeconfig for a STACKIT Kubernetes Engine (SKE) cluster.
7+
Update a kubeconfig for a STACKIT Kubernetes Engine (SKE) cluster.
8+
9+
By default, the kubeconfig information of the SKE cluster is merged into the default kubeconfig file of the current user. If the kubeconfig file doesn't exist, a new one will be created.
10+
11+
You can change the default kubeconfig destination by specifying a custom filepath with the --filepath flag.
812

9-
By default the kubeconfig is created in the .kube folder, in the user's home directory. The kubeconfig file will be overwritten if it already exists.
10-
You can override this behavior by specifying a custom filepath with the --filepath flag.
1113
An expiration time can be set for the kubeconfig. The expiration time is set in seconds(s), minutes(m), hours(h), days(d) or months(M). Default is 1h.
14+
1215
Note that the format is <value><unit>, e.g. 30d for 30 days and you can't combine units.
1316

1417
```

internal/cmd/ske/kubeconfig/create/create.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
8383
}
8484

8585
if !model.AssumeYes && !model.DisableWriting {
86-
prompt := fmt.Sprintf("Are you sure you want to create a kubeconfig for SKE cluster %q? This will OVERWRITE your current kubeconfig file, if it exists.", model.ClusterName)
86+
prompt := fmt.Sprintf("Are you sure you want to update your kubeconfig for SKE cluster %q? This will update your kubeconfig file. \n If it the kubeconfig file doesn´t exists, it will create a new one.", model.ClusterName)
8787
err = p.PromptForConfirmation(prompt)
8888
if err != nil {
8989
return err
@@ -137,10 +137,11 @@ func NewCmd(p *print.Printer) *cobra.Command {
137137
}
138138

139139
if !model.DisableWriting {
140-
err = skeUtils.WriteConfigFile(kubeconfigPath, kubeconfig)
140+
err = skeUtils.MergeKubeConfig(kubeconfigPath, kubeconfig)
141141
if err != nil {
142142
return fmt.Errorf("write kubeconfig file: %w", err)
143143
}
144+
p.Outputf("\nSet kubectl context to %s with: kubectl config use-context %s\n", model.ClusterName, model.ClusterName)
144145
}
145146

146147
return outputResult(p, model, kubeconfigPath, respKubeconfig, respLogin)
@@ -260,7 +261,7 @@ func outputResult(p *print.Printer, model *inputModel, kubeconfigPath string, re
260261
if respKubeconfig != nil {
261262
expiration = fmt.Sprintf(", with expiration date %v (UTC)", *respKubeconfig.ExpirationTimestamp)
262263
}
263-
p.Outputf("Created kubeconfig file for cluster %s in %q%s\n", model.ClusterName, kubeconfigPath, expiration)
264+
p.Outputf("Updated kubeconfig file for cluster %s in %q%s\n", model.ClusterName, kubeconfigPath, expiration)
264265

265266
return nil
266267
}

internal/pkg/services/ske/utils/utils.go

+40
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strconv"
1010

1111
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
12+
"k8s.io/client-go/tools/clientcmd"
1213

1314
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
1415
"github.com/stackitcloud/stackit-sdk-go/services/ske"
@@ -246,6 +247,45 @@ func ConvertToSeconds(timeStr string) (*string, error) {
246247
return utils.Ptr(strconv.FormatUint(result, 10)), nil
247248
}
248249

250+
// Merge new Kubeconfig into existing Kubeconfig. If it doesn´t exits, creates a new one
251+
func MergeKubeConfig(pathDestionationKubeConfig, contentNewKubeConfig string) error {
252+
if contentNewKubeConfig == "" {
253+
return fmt.Errorf("no data to merge. the new kubeconfig is empty")
254+
}
255+
256+
newConfig, err := clientcmd.Load([]byte(contentNewKubeConfig))
257+
if err != nil {
258+
return fmt.Errorf("error loading new kubeconfig: %w", err)
259+
}
260+
261+
// if the destionation kubeconfig does not exist, create a new one
262+
if _, err := os.Stat(pathDestionationKubeConfig); os.IsNotExist(err) {
263+
return WriteConfigFile(pathDestionationKubeConfig, contentNewKubeConfig)
264+
}
265+
266+
existingConfig, err := clientcmd.LoadFromFile(pathDestionationKubeConfig)
267+
if err != nil {
268+
return fmt.Errorf("error loading existing kubeconfig: %w", err)
269+
}
270+
271+
for name, authInfo := range newConfig.AuthInfos {
272+
existingConfig.AuthInfos[name] = authInfo
273+
}
274+
for name, context := range newConfig.Contexts {
275+
existingConfig.Contexts[name] = context
276+
}
277+
for name, cluster := range newConfig.Clusters {
278+
existingConfig.Clusters[name] = cluster
279+
}
280+
281+
err = clientcmd.WriteToFile(*existingConfig, pathDestionationKubeConfig)
282+
if err != nil {
283+
return fmt.Errorf("error writing merged kubeconfig: %w", err)
284+
}
285+
286+
return nil
287+
}
288+
249289
// WriteConfigFile writes the given data to the given path.
250290
// The directory is created if it does not exist.
251291
func WriteConfigFile(configPath, data string) error {

0 commit comments

Comments
 (0)