Skip to content

Commit 5760473

Browse files
Split kubeconfig retrieval and output
1 parent 9d11aee commit 5760473

File tree

2 files changed

+39
-42
lines changed

2 files changed

+39
-42
lines changed

internal/cmd/ske/kubeconfig/login/login.go

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
8080
if err != nil {
8181
return err
8282
}
83-
84-
return outputLoginKubeconfig(ctx, params.Printer, apiClient, clusterConfig)
83+
kubeconfig, err := retrieveLoginKubeconfig(ctx, apiClient, clusterConfig)
84+
if err != nil {
85+
return err
86+
}
87+
return outputLoginKubeconfig(params.Printer, clusterConfig.cacheKey, kubeconfig)
8588
},
8689
}
8790
return cmd
@@ -138,23 +141,29 @@ func parseClusterConfig(p *print.Printer, cmd *cobra.Command) (*clusterConfig, e
138141
return clusterConfig, nil
139142
}
140143

141-
func outputLoginKubeconfig(ctx context.Context, p *print.Printer, apiClient *ske.APIClient, clusterConfig *clusterConfig) error {
144+
func retrieveLoginKubeconfig(ctx context.Context, apiClient *ske.APIClient, clusterConfig *clusterConfig) (*rest.Config, error) {
142145
cachedKubeconfig := getCachedKubeConfig(clusterConfig.cacheKey)
143146
if cachedKubeconfig == nil {
144-
return GetAndOutputKubeconfig(ctx, p, apiClient, clusterConfig, nil)
147+
return requestNewLoginKubeconfig(ctx, apiClient, clusterConfig)
145148
}
146149

147150
isValid, notAfter := checkKubeconfigExpiry(cachedKubeconfig.CertData)
148151
if !isValid {
149152
// cert is expired or invalid, request new
150153
_ = cache.DeleteObject(clusterConfig.cacheKey)
151-
return GetAndOutputKubeconfig(ctx, p, apiClient, clusterConfig, nil)
154+
return requestNewLoginKubeconfig(ctx, apiClient, clusterConfig)
152155
} else if time.Now().Add(refreshBeforeDuration).After(notAfter.UTC()) {
153-
// cert expires within the next 15min, refresh (try to get a new, use cache on failure)
154-
return GetAndOutputKubeconfig(ctx, p, apiClient, clusterConfig, cachedKubeconfig)
156+
// cert expires within the next 15min -> refresh
157+
kubeconfig, err := requestNewLoginKubeconfig(ctx, apiClient, clusterConfig)
158+
// try to get a new one but use cache on failure
159+
if err != nil {
160+
return cachedKubeconfig, nil
161+
}
162+
return kubeconfig, nil
155163
}
156164
// cert not expired, nor will it expire in the next 15min; therefore, use the cached kubeconfig
157-
return output(p, clusterConfig.cacheKey, cachedKubeconfig)
165+
return cachedKubeconfig, nil
166+
158167
}
159168

160169
func getCachedKubeConfig(key string) *rest.Config {
@@ -189,63 +198,46 @@ func checkKubeconfigExpiry(certData []byte) (bool, time.Time) {
189198
return true, certificate.NotAfter.UTC()
190199
}
191200

192-
func GetAndOutputKubeconfig(ctx context.Context, p *print.Printer, apiClient *ske.APIClient, clusterConfig *clusterConfig, cachedKubeconfig *rest.Config) error {
193-
req := buildRequest(ctx, apiClient, clusterConfig)
201+
func requestNewLoginKubeconfig(ctx context.Context, apiClient *ske.APIClient, clusterConfig *clusterConfig) (*rest.Config, error) {
202+
req := buildLoginKubeconfigRequest(ctx, apiClient, clusterConfig)
194203
kubeconfigResponse, err := req.Execute()
195204
if err != nil {
196-
if cachedKubeconfig != nil {
197-
return output(p, clusterConfig.cacheKey, cachedKubeconfig)
198-
}
199-
return fmt.Errorf("request kubeconfig: %w", err)
205+
return nil, fmt.Errorf("request kubeconfig: %w", err)
200206
}
201-
202207
kubeconfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(*kubeconfigResponse.Kubeconfig))
203208
if err != nil {
204-
if cachedKubeconfig != nil {
205-
return output(p, clusterConfig.cacheKey, cachedKubeconfig)
206-
}
207-
return fmt.Errorf("parse kubeconfig: %w", err)
209+
return nil, fmt.Errorf("parse kubeconfig: %w", err)
208210
}
209211
if err = cache.PutObject(clusterConfig.cacheKey, []byte(*kubeconfigResponse.Kubeconfig)); err != nil {
210-
if cachedKubeconfig != nil {
211-
return output(p, clusterConfig.cacheKey, cachedKubeconfig)
212-
}
213-
return fmt.Errorf("cache kubeconfig: %w", err)
212+
return nil, fmt.Errorf("cache kubeconfig: %w", err)
214213
}
215214

216-
return output(p, clusterConfig.cacheKey, kubeconfig)
215+
return kubeconfig, nil
217216
}
218217

219-
func buildRequest(ctx context.Context, apiClient *ske.APIClient, clusterConfig *clusterConfig) ske.ApiCreateKubeconfigRequest {
218+
func buildLoginKubeconfigRequest(ctx context.Context, apiClient *ske.APIClient, clusterConfig *clusterConfig) ske.ApiCreateKubeconfigRequest {
220219
req := apiClient.CreateKubeconfig(ctx, clusterConfig.STACKITProjectID, clusterConfig.Region, clusterConfig.ClusterName)
221220
expirationSeconds := strconv.Itoa(expirationSeconds)
222221

223222
return req.CreateKubeconfigPayload(ske.CreateKubeconfigPayload{ExpirationSeconds: &expirationSeconds})
224223
}
225224

226-
func output(p *print.Printer, cacheKey string, kubeconfig *rest.Config) error {
227-
if kubeconfig == nil {
228-
_ = cache.DeleteObject(cacheKey)
229-
return errors.New("kubeconfig is nil")
230-
}
231-
232-
outputExecCredential, err := parseKubeConfigToExecCredential(kubeconfig)
225+
func outputLoginKubeconfig(p *print.Printer, cacheKey string, kubeconfig *rest.Config) error {
226+
output, err := parseLoginKubeConfigToExecCredential(kubeconfig)
233227
if err != nil {
234228
_ = cache.DeleteObject(cacheKey)
235229
return fmt.Errorf("convert to ExecCredential: %w", err)
236230
}
237231

238-
output, err := json.Marshal(outputExecCredential)
239-
if err != nil {
240-
_ = cache.DeleteObject(cacheKey)
241-
return fmt.Errorf("marshal ExecCredential: %w", err)
242-
}
243-
244232
p.Outputf("%s", string(output))
245233
return nil
246234
}
247235

248-
func parseKubeConfigToExecCredential(kubeconfig *rest.Config) (*clientauthenticationv1.ExecCredential, error) {
236+
func parseLoginKubeConfigToExecCredential(kubeconfig *rest.Config) ([]byte, error) {
237+
if kubeconfig == nil {
238+
return nil, errors.New("kubeconfig is nil")
239+
}
240+
249241
certPem, _ := pem.Decode(kubeconfig.CertData)
250242
if certPem == nil {
251243
return nil, fmt.Errorf("decoded pem is nil")
@@ -267,5 +259,10 @@ func parseKubeConfigToExecCredential(kubeconfig *rest.Config) (*clientauthentica
267259
ClientKeyData: string(kubeconfig.KeyData),
268260
},
269261
}
270-
return &outputExecCredential, nil
262+
263+
output, err := json.Marshal(outputExecCredential)
264+
if err != nil {
265+
return nil, fmt.Errorf("marshal: %w", err)
266+
}
267+
return output, nil
271268
}

internal/cmd/ske/kubeconfig/login/login_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func TestBuildRequest(t *testing.T) {
6262

6363
for _, tt := range tests {
6464
t.Run(tt.description, func(t *testing.T) {
65-
request := buildRequest(testCtx, testClient, tt.clusterConfig)
65+
request := buildLoginKubeconfigRequest(testCtx, testClient, tt.clusterConfig)
6666

6767
diff := cmp.Diff(request, tt.expectedRequest,
6868
cmp.AllowUnexported(tt.expectedRequest),
@@ -127,7 +127,7 @@ zbRjZmli7cnenEnfnNoFIGbgkbjGXRUCIC5zFtWXFK7kA+B2vDxD0DlLcQodNwi4
127127

128128
for _, tt := range tests {
129129
t.Run(tt.description, func(t *testing.T) {
130-
execCredential, err := parseKubeConfigToExecCredential(tt.kubeconfig)
130+
execCredential, err := parseLoginKubeConfigToExecCredential(tt.kubeconfig)
131131
if err != nil {
132132
t.Fatalf("func returned error: %s", err)
133133
}

0 commit comments

Comments
 (0)