@@ -21,6 +21,7 @@ import (
2121const (
2222 clusterNameArg = "CLUSTER_NAME"
2323
24+ loginFlag = "login"
2425 expirationFlag = "expiration"
2526 filepathFlag = "filepath"
2627)
@@ -30,6 +31,7 @@ type inputModel struct {
3031 ClusterName string
3132 Filepath * string
3233 ExpirationTime * string
34+ Login bool
3335}
3436
3537func NewCmd (p * print.Printer ) * cobra.Command {
@@ -47,6 +49,10 @@ func NewCmd(p *print.Printer) *cobra.Command {
4749 examples .NewExample (
4850 `Create a kubeconfig for the SKE cluster with name "my-cluster"` ,
4951 "$ stackit ske kubeconfig create my-cluster" ),
52+ examples .NewExample (
53+ `Create a login kubeconfig for the SKE cluster with name "my-cluster".` ,
54+ "This kubeconfig does not contain any credentials and instead obtains valid credentials via the STACKIT CLI" ,
55+ "$ stackit ske kubeconfig create my-cluster --login" ),
5056 examples .NewExample (
5157 `Create a kubeconfig for the SKE cluster with name "my-cluster" and set the expiration time to 30 days` ,
5258 "$ stackit ske kubeconfig create my-cluster --expiration 30d" ),
@@ -79,20 +85,41 @@ func NewCmd(p *print.Printer) *cobra.Command {
7985 }
8086
8187 // Call API
82- req , err := buildRequest (ctx , model , apiClient )
83- if err != nil {
84- return fmt .Errorf ("build kubeconfig create request: %w" , err )
85- }
86- resp , err := req .Execute ()
87- if err != nil {
88- return fmt .Errorf ("create kubeconfig for SKE cluster: %w" , err )
88+ var (
89+ kubeconfig string
90+ respKubeconfig * ske.Kubeconfig
91+ respLogin * ske.V1LoginKubeconfig
92+ )
93+
94+ if ! model .Login {
95+ req , err := buildRequestCreate (ctx , model , apiClient )
96+ if err != nil {
97+ return fmt .Errorf ("build kubeconfig create request: %w" , err )
98+ }
99+ respKubeconfig , err = req .Execute ()
100+ if err != nil {
101+ return fmt .Errorf ("create kubeconfig for SKE cluster: %w" , err )
102+ }
103+ if respKubeconfig .Kubeconfig == nil {
104+ return fmt .Errorf ("no kubeconfig returned from the API" )
105+ }
106+ kubeconfig = * respKubeconfig .Kubeconfig
107+ } else {
108+ req , err := buildRequestLogin (ctx , model , apiClient )
109+ if err != nil {
110+ return fmt .Errorf ("build login kubeconfig create request: %w" , err )
111+ }
112+ respLogin , err = req .Execute ()
113+ if err != nil {
114+ return fmt .Errorf ("create login kubeconfig for SKE cluster: %w" , err )
115+ }
116+ if respLogin .Kubeconfig == nil {
117+ return fmt .Errorf ("no login kubeconfig returned from the API" )
118+ }
119+ kubeconfig = * respLogin .Kubeconfig
89120 }
90121
91122 // Create the config file
92- if resp .Kubeconfig == nil {
93- return fmt .Errorf ("no kubeconfig returned from the API" )
94- }
95-
96123 var kubeconfigPath string
97124 if model .Filepath == nil {
98125 kubeconfigPath , err = skeUtils .GetDefaultKubeconfigPath ()
@@ -103,21 +130,26 @@ func NewCmd(p *print.Printer) *cobra.Command {
103130 kubeconfigPath = * model .Filepath
104131 }
105132
106- err = skeUtils .WriteConfigFile (kubeconfigPath , * resp .Kubeconfig )
107- if err != nil {
108- return fmt .Errorf ("write kubeconfig file: %w" , err )
133+ if model .OutputFormat != print .JSONOutputFormat {
134+ err = skeUtils .WriteConfigFile (kubeconfigPath , kubeconfig )
135+ if err != nil {
136+ return fmt .Errorf ("write kubeconfig file: %w" , err )
137+ }
109138 }
110139
111- return outputResult (p , model , kubeconfigPath , resp )
140+ return outputResult (p , model , kubeconfigPath , respKubeconfig , respLogin )
112141 },
113142 }
114143 configureFlags (cmd )
115144 return cmd
116145}
117146
118147func configureFlags (cmd * cobra.Command ) {
148+ 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." )
119149 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" )
120150 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." )
151+
152+ cmd .MarkFlagsMutuallyExclusive (loginFlag , expirationFlag )
121153}
122154
123155func parseInput (p * print.Printer , cmd * cobra.Command , inputArgs []string ) (* inputModel , error ) {
@@ -146,6 +178,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu
146178 ClusterName : clusterName ,
147179 Filepath : flags .FlagToStringPointer (p , cmd , filepathFlag ),
148180 ExpirationTime : expTime ,
181+ Login : flags .FlagToBoolValue (p , cmd , loginFlag ),
149182 }
150183
151184 if p .IsVerbosityDebug () {
@@ -160,7 +193,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu
160193 return & model , nil
161194}
162195
163- func buildRequest (ctx context.Context , model * inputModel , apiClient * ske.APIClient ) (ske.ApiCreateKubeconfigRequest , error ) {
196+ func buildRequestCreate (ctx context.Context , model * inputModel , apiClient * ske.APIClient ) (ske.ApiCreateKubeconfigRequest , error ) {
164197 req := apiClient .CreateKubeconfig (ctx , model .ProjectId , model .ClusterName )
165198
166199 payload := ske.CreateKubeconfigPayload {}
@@ -172,18 +205,32 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *ske.APIClie
172205 return req .CreateKubeconfigPayload (payload ), nil
173206}
174207
175- func outputResult (p * print.Printer , model * inputModel , kubeconfigPath string , resp * ske.Kubeconfig ) error {
208+ func buildRequestLogin (ctx context.Context , model * inputModel , apiClient * ske.APIClient ) (ske.ApiGetLoginKubeconfigRequest , error ) {
209+ return apiClient .GetLoginKubeconfig (ctx , model .ProjectId , model .ClusterName ), nil
210+ }
211+
212+ func outputResult (p * print.Printer , model * inputModel , kubeconfigPath string , respKubeconfig * ske.Kubeconfig , respLogin * ske.V1LoginKubeconfig ) error {
176213 switch model .OutputFormat {
177214 case print .JSONOutputFormat :
178- details , err := json .MarshalIndent (resp , "" , " " )
215+ var err error
216+ var details []byte
217+ if respKubeconfig != nil {
218+ details , err = json .MarshalIndent (respKubeconfig , "" , " " )
219+ } else if respLogin != nil {
220+ details , err = json .MarshalIndent (respLogin , "" , " " )
221+ }
179222 if err != nil {
180223 return fmt .Errorf ("marshal SKE Kubeconfig: %w" , err )
181224 }
182225 p .Outputln (string (details ))
183226
184227 return nil
185228 default :
186- p .Outputf ("Created kubeconfig file for cluster %s in %q, with expiration date %v (UTC)\n " , model .ClusterName , kubeconfigPath , * resp .ExpirationTimestamp )
229+ var expiration string
230+ if respKubeconfig != nil {
231+ expiration = fmt .Sprintf (", with expiration date %v (UTC)" , * respKubeconfig .ExpirationTimestamp )
232+ }
233+ p .Outputf ("Created kubeconfig file for cluster %s in %q%s\n " , model .ClusterName , kubeconfigPath , expiration )
187234
188235 return nil
189236 }
0 commit comments