From 4f25d16dc4bce52ef41eca3fa486e5973b992ad0 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 10 Jan 2025 13:26:48 +0100 Subject: [PATCH 1/3] Fix: Kubeconfig doesn't get written when output format is json - Add flag to disable the writing of kubeconfig --- docs/stackit_ske_kubeconfig_create.md | 4 +++ internal/cmd/ske/kubeconfig/create/create.go | 25 +++++++++++++++---- .../cmd/ske/kubeconfig/create/create_test.go | 21 ++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/docs/stackit_ske_kubeconfig_create.md b/docs/stackit_ske_kubeconfig_create.md index a779cacc0..28238e645 100644 --- a/docs/stackit_ske_kubeconfig_create.md +++ b/docs/stackit_ske_kubeconfig_create.md @@ -32,11 +32,15 @@ stackit ske kubeconfig create CLUSTER_NAME [flags] Create a kubeconfig for the SKE cluster with name "my-cluster" in a custom filepath $ stackit ske kubeconfig create my-cluster --filepath /path/to/config + + Get a kubeconfig for the SKE cluster with name "my-cluster" without writing it to a file. + ``` ### Options ``` + --disable-writing Disable writing to the kubeconfig file. -e, --expiration string Expiration time for the kubeconfig in seconds(s), minutes(m), hours(h), days(d) or months(M). Example: 30d. By default, expiration time is 1h --filepath string Path to create the kubeconfig file. By default, the kubeconfig is created as 'config' in the .kube folder, in the user's home directory. -h, --help Help for "stackit ske kubeconfig create" diff --git a/internal/cmd/ske/kubeconfig/create/create.go b/internal/cmd/ske/kubeconfig/create/create.go index 53310c43f..4f23c8fd8 100644 --- a/internal/cmd/ske/kubeconfig/create/create.go +++ b/internal/cmd/ske/kubeconfig/create/create.go @@ -22,9 +22,10 @@ import ( const ( clusterNameArg = "CLUSTER_NAME" - loginFlag = "login" - expirationFlag = "expiration" - filepathFlag = "filepath" + loginFlag = "login" + expirationFlag = "expiration" + filepathFlag = "filepath" + disableWritingFlag = "disable-writing" ) type inputModel struct { @@ -33,6 +34,7 @@ type inputModel struct { Filepath *string ExpirationTime *string Login bool + DisableWriting bool } func NewCmd(p *print.Printer) *cobra.Command { @@ -63,6 +65,9 @@ func NewCmd(p *print.Printer) *cobra.Command { examples.NewExample( `Create a kubeconfig for the SKE cluster with name "my-cluster" in a custom filepath`, "$ stackit ske kubeconfig create my-cluster --filepath /path/to/config"), + examples.NewExample( + `Get a kubeconfig for the SKE cluster with name "my-cluster" without writing it to a file. `, + ""), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -77,7 +82,7 @@ func NewCmd(p *print.Printer) *cobra.Command { return err } - if !model.AssumeYes { + if !model.AssumeYes && !model.DisableWriting { 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) err = p.PromptForConfirmation(prompt) if err != nil { @@ -131,7 +136,7 @@ func NewCmd(p *print.Printer) *cobra.Command { kubeconfigPath = *model.Filepath } - if model.OutputFormat != print.JSONOutputFormat { + if !model.DisableWriting { err = skeUtils.WriteConfigFile(kubeconfigPath, kubeconfig) if err != nil { return fmt.Errorf("write kubeconfig file: %w", err) @@ -149,6 +154,7 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().BoolP(loginFlag, "l", false, "Create a login kubeconfig that obtains valid credentials via the STACKIT CLI. This flag is mutually exclusive with the expiration flag.") cmd.Flags().StringP(expirationFlag, "e", "", "Expiration time for the kubeconfig in seconds(s), minutes(m), hours(h), days(d) or months(M). Example: 30d. By default, expiration time is 1h") cmd.Flags().String(filepathFlag, "", "Path to create the kubeconfig file. By default, the kubeconfig is created as 'config' in the .kube folder, in the user's home directory.") + cmd.Flags().Bool(disableWritingFlag, false, fmt.Sprintf("Disable the writing of kubeconfig. Add --%s to display the kubeconfig.", globalflags.OutputFormatFlag)) cmd.MarkFlagsMutuallyExclusive(loginFlag, expirationFlag) } @@ -174,12 +180,21 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } } + disableWriting := flags.FlagToBoolValue(p, cmd, disableWritingFlag) + + isDefaultOutputFormat := globalFlags.OutputFormat != print.JSONOutputFormat && globalFlags.OutputFormat != print.YAMLOutputFormat + if disableWriting && isDefaultOutputFormat { + return nil, fmt.Errorf("when setting the flag --%s, you must specify --%s as one of the values: %s", + disableWritingFlag, globalflags.OutputFormatFlag, fmt.Sprintf("%s, %s", print.JSONOutputFormat, print.YAMLOutputFormat)) + } + model := inputModel{ GlobalFlagModel: globalFlags, ClusterName: clusterName, Filepath: flags.FlagToStringPointer(p, cmd, filepathFlag), ExpirationTime: expTime, Login: flags.FlagToBoolValue(p, cmd, loginFlag), + DisableWriting: disableWriting, } if p.IsVerbosityDebug() { diff --git a/internal/cmd/ske/kubeconfig/create/create_test.go b/internal/cmd/ske/kubeconfig/create/create_test.go index 86fb29ac4..bae59d3bb 100644 --- a/internal/cmd/ske/kubeconfig/create/create_test.go +++ b/internal/cmd/ske/kubeconfig/create/create_test.go @@ -156,6 +156,27 @@ func TestParseInput(t *testing.T) { }), isValid: false, }, + { + description: "disable writing and invalid output format", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[disableWritingFlag] = "true" + }), + isValid: false, + }, + { + description: "disable writing and valid output format", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[disableWritingFlag] = "true" + flagValues[globalflags.OutputFormatFlag] = print.YAMLOutputFormat + }), + expectedModel: fixtureInputModel(func(model *inputModel) { + model.DisableWriting = true + model.OutputFormat = print.YAMLOutputFormat + }), + isValid: true, + }, } for _, tt := range tests { From bd7f31a59ec68b60abc02fb1f4dfa1d56ac15081 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 10 Jan 2025 16:40:49 +0100 Subject: [PATCH 2/3] Refinement: Examples and descriptions for --disable-writing --- internal/cmd/ske/kubeconfig/create/create.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/cmd/ske/kubeconfig/create/create.go b/internal/cmd/ske/kubeconfig/create/create.go index 4f23c8fd8..b819dab6c 100644 --- a/internal/cmd/ske/kubeconfig/create/create.go +++ b/internal/cmd/ske/kubeconfig/create/create.go @@ -66,8 +66,8 @@ func NewCmd(p *print.Printer) *cobra.Command { `Create a kubeconfig for the SKE cluster with name "my-cluster" in a custom filepath`, "$ stackit ske kubeconfig create my-cluster --filepath /path/to/config"), examples.NewExample( - `Get a kubeconfig for the SKE cluster with name "my-cluster" without writing it to a file. `, - ""), + `Get a kubeconfig for the SKE cluster with name "my-cluster" without writing it to a file and format the output as json`, + "$ stackit ske kubeconfig create my-cluster --disable-writing --output-format json"), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -154,7 +154,7 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().BoolP(loginFlag, "l", false, "Create a login kubeconfig that obtains valid credentials via the STACKIT CLI. This flag is mutually exclusive with the expiration flag.") cmd.Flags().StringP(expirationFlag, "e", "", "Expiration time for the kubeconfig in seconds(s), minutes(m), hours(h), days(d) or months(M). Example: 30d. By default, expiration time is 1h") cmd.Flags().String(filepathFlag, "", "Path to create the kubeconfig file. By default, the kubeconfig is created as 'config' in the .kube folder, in the user's home directory.") - cmd.Flags().Bool(disableWritingFlag, false, fmt.Sprintf("Disable the writing of kubeconfig. Add --%s to display the kubeconfig.", globalflags.OutputFormatFlag)) + cmd.Flags().Bool(disableWritingFlag, false, fmt.Sprintf("Disable the writing of kubeconfig. Set the output format to json or yaml using the --%s flag to display the kubeconfig.", globalflags.OutputFormatFlag)) cmd.MarkFlagsMutuallyExclusive(loginFlag, expirationFlag) } @@ -182,8 +182,9 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu disableWriting := flags.FlagToBoolValue(p, cmd, disableWritingFlag) - isDefaultOutputFormat := globalFlags.OutputFormat != print.JSONOutputFormat && globalFlags.OutputFormat != print.YAMLOutputFormat - if disableWriting && isDefaultOutputFormat { + fmt.Println(globalFlags.OutputFormat) + isInvalidOutputFormat := globalFlags.OutputFormat == "" || globalFlags.OutputFormat == print.NoneOutputFormat || globalFlags.OutputFormat == print.PrettyOutputFormat + if disableWriting && isInvalidOutputFormat { return nil, fmt.Errorf("when setting the flag --%s, you must specify --%s as one of the values: %s", disableWritingFlag, globalflags.OutputFormatFlag, fmt.Sprintf("%s, %s", print.JSONOutputFormat, print.YAMLOutputFormat)) } From 934ea5a739a4947e665f1b6d136f9b9c0df928de Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 10 Jan 2025 16:48:54 +0100 Subject: [PATCH 3/3] Remove debug print --- internal/cmd/ske/kubeconfig/create/create.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/cmd/ske/kubeconfig/create/create.go b/internal/cmd/ske/kubeconfig/create/create.go index b819dab6c..be86251ab 100644 --- a/internal/cmd/ske/kubeconfig/create/create.go +++ b/internal/cmd/ske/kubeconfig/create/create.go @@ -182,7 +182,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu disableWriting := flags.FlagToBoolValue(p, cmd, disableWritingFlag) - fmt.Println(globalFlags.OutputFormat) isInvalidOutputFormat := globalFlags.OutputFormat == "" || globalFlags.OutputFormat == print.NoneOutputFormat || globalFlags.OutputFormat == print.PrettyOutputFormat if disableWriting && isInvalidOutputFormat { return nil, fmt.Errorf("when setting the flag --%s, you must specify --%s as one of the values: %s",