Skip to content

Commit 8793732

Browse files
Merge pull request #1523 from sttts/sttts-home-retry-after-typo
server/home: avoid returning an uninitialized ~ workspace
2 parents 648bcfd + 736ac40 commit 8793732

File tree

4 files changed

+115
-66
lines changed

4 files changed

+115
-66
lines changed

pkg/server/home_workspaces.go

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"net/url"
2727
"regexp"
2828
"strings"
29-
"time"
3029

3130
"github.com/kcp-dev/logicalcluster"
3231

@@ -61,9 +60,6 @@ const (
6160
homeOwnerClusterRolePrefix = "system:kcp:tenancy:home-owner:"
6261
HomeBucketClusterWorkspaceType = "homebucket"
6362
HomeClusterWorkspaceType = "home"
64-
65-
// the amount of time while the create delay is repeatedly returned to the client
66-
createDelayTimeout = time.Minute
6763
)
6864

6965
var (
@@ -194,9 +190,9 @@ type homeWorkspaceHandlerBuilder struct {
194190
}
195191

196192
type homeWorkspaceFeatureLogic struct {
197-
searchForHomeWorkspaceRBACResourcesInLocalInformers func(homeWorkspace logicalcluster.Name, userName string) (found bool, err error)
193+
searchForHomeWorkspaceRBACResourcesInLocalInformers func(homeWorkspace logicalcluster.Name) (found bool, err error)
198194
createHomeWorkspaceRBACResources func(ctx context.Context, userName string, homeWorkspace logicalcluster.Name) error
199-
searchForReadyWorkspaceInLocalInformers func(logicalClusterName logicalcluster.Name, isHome bool, userName string) (readyAndRBACAsExpected bool, retryAfterSeconds int, checkError error)
195+
searchForWorkspaceAndRBACInLocalInformers func(logicalClusterName logicalcluster.Name, isHome bool, userName string) (readyAndRBACAsExpected bool, retryAfterSeconds int, checkError error)
200196
tryToCreate func(ctx context.Context, userName string, workspaceToCheck logicalcluster.Name, workspaceType tenancyv1alpha1.ClusterWorkspaceTypeName) (retryAfterSeconds int, createError error)
201197
}
202198

@@ -209,14 +205,14 @@ func (b homeWorkspaceHandlerBuilder) build() *homeWorkspaceHandler {
209205
h := &homeWorkspaceHandler{}
210206
h.homeWorkspaceHandlerBuilder = b
211207
h.homeWorkspaceFeatureLogic = homeWorkspaceFeatureLogic{
212-
searchForHomeWorkspaceRBACResourcesInLocalInformers: func(logicalClusterName logicalcluster.Name, userName string) (found bool, err error) {
213-
return searchForHomeWorkspaceRBACResourcesInLocalInformers(h, logicalClusterName, userName)
208+
searchForHomeWorkspaceRBACResourcesInLocalInformers: func(logicalClusterName logicalcluster.Name) (found bool, err error) {
209+
return searchForHomeWorkspaceRBACResourcesInLocalInformers(h, logicalClusterName)
214210
},
215211
createHomeWorkspaceRBACResources: func(ctx context.Context, userName string, logicalClusterName logicalcluster.Name) error {
216212
return createHomeWorkspaceRBACResources(h, ctx, userName, logicalClusterName)
217213
},
218-
searchForReadyWorkspaceInLocalInformers: func(logicalClusterName logicalcluster.Name, isHome bool, userName string) (found bool, retryAfterSeconds int, checkError error) {
219-
return searchForReadyWorkspaceInLocalInformers(h, logicalClusterName, isHome, userName)
214+
searchForWorkspaceAndRBACInLocalInformers: func(logicalClusterName logicalcluster.Name, isHome bool, userName string) (found bool, retryAfterSeconds int, checkError error) {
215+
return searchForWorkspaceAndRBACInLocalInformers(h, logicalClusterName, isHome, userName)
220216
},
221217
tryToCreate: func(ctx context.Context, userName string, logicalClusterName logicalcluster.Name, workspaceType tenancyv1alpha1.ClusterWorkspaceTypeName) (retryAfterSeconds int, createError error) {
222218
return tryToCreate(h, ctx, userName, logicalClusterName, workspaceType)
@@ -272,28 +268,27 @@ func (h *homeWorkspaceHandler) ServeHTTP(rw http.ResponseWriter, req *http.Reque
272268
// underlying ClusterWorkspace resource exists.
273269

274270
homeLogicalClusterName := h.getHomeLogicalClusterName(effectiveUser.GetName())
271+
275272
homeClusterWorkspace, err := h.localInformers.getClusterWorkspace(homeLogicalClusterName)
276273
if err != nil && !kerrors.IsNotFound(err) {
277274
responsewriters.InternalError(rw, req, err)
278275
return
279276
}
280277
if homeClusterWorkspace != nil {
281-
if homeClusterWorkspace.Status.Phase != tenancyv1alpha1.ClusterWorkspacePhaseReady {
282-
if h.creationDelaySeconds > 0 && time.Now().After(homeClusterWorkspace.CreationTimestamp.Add(createDelayTimeout)) {
283-
// Return a 429 status asking the client to try again after the creationDelay
284-
rw.Header().Set("Retry-After", fmt.Sprintf("%d", h.creationDelaySeconds))
285-
http.Error(rw, "Creating the home workspace", http.StatusTooManyRequests)
286-
return
287-
}
278+
if found, err := h.searchForHomeWorkspaceRBACResourcesInLocalInformers(homeLogicalClusterName); err != nil {
279+
responsewriters.InternalError(rw, req, err)
280+
return
281+
} else if found && homeClusterWorkspace.Status.Phase == tenancyv1alpha1.ClusterWorkspacePhaseReady {
282+
// We don't need to check any permission before returning the home workspace definition since,
283+
// once it has been created, a home workspace is owned by the user.
284+
285+
homeWorkspace := &tenancyv1beta1.Workspace{}
286+
projection.ProjectClusterWorkspaceToWorkspace(homeClusterWorkspace, homeWorkspace)
287+
responsewriters.WriteObjectNegotiated(homeWorkspaceCodecs, negotiation.DefaultEndpointRestrictions, tenancyv1beta1.SchemeGroupVersion, rw, req, http.StatusOK, homeWorkspace)
288+
return
288289
}
289290

290-
// We don't need to check any permission before returning the home workspace definition since,
291-
// once it has been created, a home workspace is owned by the user.
292-
293-
homeWorkspace := &tenancyv1beta1.Workspace{}
294-
projection.ProjectClusterWorkspaceToWorkspace(homeClusterWorkspace, homeWorkspace)
295-
responsewriters.WriteObjectNegotiated(homeWorkspaceCodecs, negotiation.DefaultEndpointRestrictions, tenancyv1beta1.SchemeGroupVersion, rw, req, http.StatusOK, homeWorkspace)
296-
return
291+
// fall through because either not ready or RBAC objects missing
297292
}
298293

299294
// Test if the user has the right to see his Home workspace even though it doesn't exists
@@ -348,7 +343,7 @@ func (h *homeWorkspaceHandler) ServeHTTP(rw http.ResponseWriter, req *http.Reque
348343
}
349344

350345
isHome := workspaceType == HomeClusterWorkspaceType
351-
if foundLocally, retryAfterSeconds, err := h.searchForReadyWorkspaceInLocalInformers(lcluster.Name, isHome, effectiveUser.GetName()); err != nil {
346+
if foundLocally, retryAfterSeconds, err := h.searchForWorkspaceAndRBACInLocalInformers(lcluster.Name, isHome, effectiveUser.GetName()); err != nil {
352347
responsewriters.InternalError(rw, req, err)
353348
return
354349
} else if foundLocally {
@@ -467,13 +462,12 @@ func (h *homeWorkspaceHandler) needsAutomaticCreation(logicalClusterName logical
467462
}
468463
}
469464

470-
// searchForReadyWorkspaceInLocalInformers checks whether a workspace is known on the current shard
465+
// searchForWorkspaceAndRBACInLocalInformers checks whether a workspace is known on the current shard
471466
// in local informers.
472467
// For home workspaces, we also check:
473468
// - if related RBAC resources are there,
474-
// - if the workspace phase is READY
475469
// and if not answer to retry later.
476-
func searchForReadyWorkspaceInLocalInformers(h *homeWorkspaceHandler, logicalClusterName logicalcluster.Name, isHome bool, userName string) (readyAndRBACAsExpected bool, retryAfterSeconds int, err error) {
470+
func searchForWorkspaceAndRBACInLocalInformers(h *homeWorkspaceHandler, logicalClusterName logicalcluster.Name, isHome bool, userName string) (readyAndRBACAsExpected bool, retryAfterSeconds int, err error) {
477471
workspace, err := h.localInformers.getClusterWorkspace(logicalClusterName)
478472
if err != nil && !kerrors.IsNotFound(err) {
479473
return false, 0, err
@@ -507,7 +501,7 @@ func searchForReadyWorkspaceInLocalInformers(h *homeWorkspaceHandler, logicalClu
507501
}
508502

509503
// For home workspaces, also wait for related RBAC resources to be setup.
510-
if rbacResourcesFound, err := h.searchForHomeWorkspaceRBACResourcesInLocalInformers(logicalClusterName, userName); err != nil {
504+
if rbacResourcesFound, err := h.searchForHomeWorkspaceRBACResourcesInLocalInformers(logicalClusterName); err != nil {
511505
return false, 0, err
512506
} else if !rbacResourcesFound {
513507
// Retry sooner than the creation delay, because it's probably a question of
@@ -610,7 +604,7 @@ func tryToCreate(h *homeWorkspaceHandler, ctx context.Context, userName string,
610604

611605
// searchForHomeWorkspaceRBACResourcesInLocalInformers searches for the expected RBAC resources associated to a Home workspace
612606
// in the local informers.
613-
func searchForHomeWorkspaceRBACResourcesInLocalInformers(h *homeWorkspaceHandler, logicalClusterName logicalcluster.Name, userName string) (found bool, err error) {
607+
func searchForHomeWorkspaceRBACResourcesInLocalInformers(h *homeWorkspaceHandler, logicalClusterName logicalcluster.Name) (found bool, err error) {
614608
parent, workspaceName := logicalClusterName.Split()
615609

616610
if _, err := h.localInformers.getClusterRole(parent, homeOwnerClusterRolePrefix+workspaceName); kerrors.IsNotFound(err) {

0 commit comments

Comments
 (0)