From 49aa7e71f4c2d3eefa135735bad4a27707703c63 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 20 Sep 2023 18:17:30 +0200 Subject: [PATCH 01/26] add available roles to workspace api --- go.mod | 4 +- go.sum | 2 + pkg/application/service/services.go | 1 + pkg/informers/informers.go | 1 + pkg/informers/service/informer_service.go | 15 ++ pkg/proxy/handlers/spacelister.go | 185 ++++++++++++++++------ pkg/proxy/handlers/spacelister_test.go | 95 +++++++++-- test/fake/informer.go | 8 + test/fake/proxy.go | 50 ++++++ 9 files changed, 300 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index df4d3267..9e773ca9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/aws/aws-sdk-go v1.44.100 - github.com/codeready-toolchain/api v0.0.0-20230912073725-4ae0201b4630 + github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33 github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3 github.com/go-logr/logr v1.2.3 github.com/gofrs/uuid v4.2.0+incompatible @@ -147,3 +147,5 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace github.com/codeready-toolchain/toolchain-common => /Users/fmuntean/go/src/github.com/codeready-toolchain/toolchain-common \ No newline at end of file diff --git a/go.sum b/go.sum index 357f974c..e27185bd 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,8 @@ github.com/codeready-toolchain/api v0.0.0-20230818091928-38277763fa2d h1:aV4QEU4 github.com/codeready-toolchain/api v0.0.0-20230818091928-38277763fa2d/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/codeready-toolchain/api v0.0.0-20230912073725-4ae0201b4630 h1:Z281nLD0OLfdzbUq2tUK5/B6d2OX1hPg5oFGZSJM4RQ= github.com/codeready-toolchain/api v0.0.0-20230912073725-4ae0201b4630/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= +github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33 h1:hxXfcFq2JgFISVxrkISg8m9DZMzpcPWRjPspx3M3Sxo= +github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3 h1:zPxv/JJRZsXS+OVgsrF1egFlTi45DXJ8MTPi50meujI= github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3/go.mod h1:vtUfWOJBDxQP1DtcIoxfjI5heBGcT8D+C8ux+PLouyg= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= diff --git a/pkg/application/service/services.go b/pkg/application/service/services.go index f9af5cf3..4d15b6b0 100644 --- a/pkg/application/service/services.go +++ b/pkg/application/service/services.go @@ -15,6 +15,7 @@ type InformerService interface { GetUserSignup(name string) (*toolchainv1alpha1.UserSignup, error) ListSpaceBindings(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) GetProxyPluginConfig(name string) (*toolchainv1alpha1.ProxyPlugin, error) + GetNSTemplateTier(name string) (*toolchainv1alpha1.NSTemplateTier, error) } type SignupService interface { diff --git a/pkg/informers/informers.go b/pkg/informers/informers.go index 17b04a79..92dccced 100644 --- a/pkg/informers/informers.go +++ b/pkg/informers/informers.go @@ -22,6 +22,7 @@ type Informer struct { ToolchainStatus cache.GenericLister UserSignup cache.GenericLister ProxyPluginConfig cache.GenericLister + NSTemplateTier cache.GenericLister } func StartInformer(cfg *rest.Config) (*Informer, chan struct{}, error) { diff --git a/pkg/informers/service/informer_service.go b/pkg/informers/service/informer_service.go index cee7608e..ab1ce673 100644 --- a/pkg/informers/service/informer_service.go +++ b/pkg/informers/service/informer_service.go @@ -130,3 +130,18 @@ func (s *ServiceImpl) ListSpaceBindings(reqs ...labels.Requirement) ([]toolchain } return sbs, err } + +func (s *ServiceImpl) GetNSTemplateTier(name string) (*toolchainv1alpha1.NSTemplateTier, error) { + obj, err := s.informer.NSTemplateTier.ByNamespace(configuration.Namespace()).Get(name) + if err != nil { + return nil, err + } + + unobj := obj.(*unstructured.Unstructured) + tier := &toolchainv1alpha1.NSTemplateTier{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unobj.UnstructuredContent(), tier); err != nil { + log.Errorf(nil, err, "failed to get NSTemplateTier '%s'", name) + return nil, err + } + return tier, err +} diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 1e7824d8..c8c29092 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "sort" toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" "github.com/codeready-toolchain/registration-service/pkg/application" @@ -25,6 +26,7 @@ import ( type SpaceLister struct { GetSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupCompleted bool) (*signup.Signup, error) + GetNSTemplateTierFunc func(ctx *gin.Context, tier string) (*toolchainv1alpha1.NSTemplateTier, error) GetInformerServiceFunc func() service.InformerService } @@ -37,26 +39,86 @@ func NewSpaceLister(app application.Application) *SpaceLister { func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { - workspaces, err := s.ListUserWorkspaces(ctx) + userID, _ := ctx.Get(context.SubKey).(string) + username, _ := ctx.Get(context.UsernameKey).(string) + workspaceName := ctx.Param("workspace") + doGetWorkspace := len(workspaceName) > 0 + + userSignup, err := s.GetSignupFunc(nil, userID, username, false) if err != nil { + ctx.Logger().Error(errs.Wrap(err, "error retrieving userSignup")) return errorResponse(ctx, apierrors.NewInternalError(err)) } + if userSignup == nil || userSignup.CompliantUsername == "" { + // account exists but the compliant username is not set yet, meaning it has not been fully provisioned yet + if doGetWorkspace { + // return not found response when specific workspace request was issued + r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} + return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) - workspaceName := ctx.Param("workspace") - doGetWorkspace := len(workspaceName) > 0 + } else { + // return empty workspace list + return listWorkspaceResponse(ctx, []toolchainv1alpha1.Workspace{}) + } + } - if doGetWorkspace { // specific workspace requested - if len(workspaces) != 1 { + // get specific workspace + if doGetWorkspace { + workspace, err := s.GetUserWorkspace(ctx, userSignup) + if err != nil { + return errorResponse(ctx, apierrors.NewInternalError(err)) + } + if workspace == nil { // not found r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) } - return getWorkspaceResponse(ctx, workspaces[0]) + return getWorkspaceResponse(ctx, workspace) } + // list all user workspaces + workspaces, err := s.ListUserWorkspaces(ctx) + if err != nil { + return errorResponse(ctx, apierrors.NewInternalError(err)) + } return listWorkspaceResponse(ctx, workspaces) } +func (s *SpaceLister) GetUserWorkspace(ctx echo.Context, signup *signup.Signup) (*toolchainv1alpha1.Workspace, error) { + murName := signup.CompliantUsername + spaceBinding, err := s.listSpaceBindingForUserAndSpace(ctx, murName) + if err != nil { + ctx.Logger().Error(errs.Wrap(err, "error listing space bindings")) + return nil, err + } + if spaceBinding == nil { + // spacebinding not found, let's return a nil workspace which causes the handler to respond with a 404 status code + return nil, nil + } + + space, err := s.getSpace(spaceBinding) + if err != nil { + ctx.Logger().Error(errs.Wrap(err, "unable to get space")) + return nil, err + } + + // ------------- + // TODO recursively get all the spacebindings for the current workspace + // and build the Bindings list with the available actions + // this field is populated only for the GET workspace request + // ------------- + + // add available roles, this field is populated only for the GET workspace request + nsTemplateTier, err := s.GetNSTemplateTierFunc(nil, space.Spec.TierName) + if err != nil { + ctx.Logger().Error(errs.Wrap(err, "unable to get nstemplatetier")) + return nil, err + } + getOnlyWSOptions := commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)) + + return createCommonWorkspace(signup.Name, space, spaceBinding, getOnlyWSOptions), nil +} + func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1.Workspace, error) { userID, _ := ctx.Get(context.SubKey).(string) username, _ := ctx.Get(context.UsernameKey).(string) @@ -72,7 +134,7 @@ func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1. } murName := signup.CompliantUsername - spaceBindings, err := s.listSpaceBindingsForUser(ctx, murName) + spaceBindings, err := s.listSpaceBindingsForUser(murName) if err != nil { ctx.Logger().Error(errs.Wrap(err, "error listing space bindings")) return nil, err @@ -81,68 +143,97 @@ func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1. return s.workspacesFromSpaceBindings(signup.Name, spaceBindings), nil } -func (s *SpaceLister) listSpaceBindingsForUser(ctx echo.Context, murName string) ([]toolchainv1alpha1.SpaceBinding, error) { +func (s *SpaceLister) listSpaceBindingsForUser(murName string) ([]toolchainv1alpha1.SpaceBinding, error) { + murSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingMasterUserRecordLabelKey, selection.Equals, []string{murName}) + if err != nil { + return nil, err + } + requirements := []labels.Requirement{*murSelector} + return s.GetInformerServiceFunc().ListSpaceBindings(requirements...) +} +func (s *SpaceLister) listSpaceBindingForUserAndSpace(ctx echo.Context, murName string) (*toolchainv1alpha1.SpaceBinding, error) { workspaceName := ctx.Param("workspace") - doGetWorkspace := len(workspaceName) > 0 - murSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingMasterUserRecordLabelKey, selection.Equals, []string{murName}) if err != nil { return nil, err } + // specific workspace requested so add label requirement to match the space + spaceSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingSpaceLabelKey, selection.Equals, []string{workspaceName}) + if err != nil { + return nil, err + } + requirements := []labels.Requirement{*murSelector, *spaceSelector} - requirements := []labels.Requirement{*murSelector} + spaceBindings, err := s.GetInformerServiceFunc().ListSpaceBindings(requirements...) + if err != nil { + return nil, err + } - if doGetWorkspace { - // specific workspace requested so add label requirement to match the space - spaceSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingSpaceLabelKey, selection.Equals, []string{workspaceName}) - if err != nil { - return nil, err - } - requirements = append(requirements, *spaceSelector) + // let's only log the issue and consider this as not found + if len(spaceBindings) != 1 { + ctx.Logger().Error("expected only 1 spacebinding, got %d for user %s and workspace %s", len(spaceBindings), murName, workspaceName) + return nil, nil } - return s.GetInformerServiceFunc().ListSpaceBindings(requirements...) + return &spaceBindings[0], nil } -func (s *SpaceLister) workspacesFromSpaceBindings(signupName string, spaceBindings []toolchainv1alpha1.SpaceBinding) []toolchainv1alpha1.Workspace { +func (s *SpaceLister) workspacesFromSpaceBindings(signupName string, spaceBindings []toolchainv1alpha1.SpaceBinding, wsAdditionalOptions ...commonproxy.WorkspaceOption) []toolchainv1alpha1.Workspace { workspaces := []toolchainv1alpha1.Workspace{} for _, spaceBinding := range spaceBindings { - - var ownerName string - spaceName := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey] - if spaceName == "" { // space may not be initialized - // log error and continue so that the api behaves in a best effort manner - log.Errorf(nil, fmt.Errorf("spacebinding has no '%s' label", toolchainv1alpha1.SpaceBindingSpaceLabelKey), "unable to get space", "space", spaceName) - continue - } - space, err := s.GetInformerServiceFunc().GetSpace(spaceName) + space, err := s.getSpace(&spaceBinding) if err != nil { // log error and continue so that the api behaves in a best effort manner // ie. if a space isn't listed something went wrong but we still want to return the other spaces if possible - log.Errorf(nil, err, "unable to get space", "space", spaceName) + log.Errorf(nil, err, "unable to get space", "space", spaceBinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey]) continue } + workspace := createCommonWorkspace(signupName, space, &spaceBinding) + workspaces = append(workspaces, *workspace) + } + return workspaces +} - // TODO right now we get SpaceCreatorLabelKey but should get owner from Space once it's implemented - ownerName = space.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] +func createCommonWorkspace(signupName string, space *toolchainv1alpha1.Space, spaceBinding *toolchainv1alpha1.SpaceBinding, wsAdditionalOptions ...commonproxy.WorkspaceOption) *toolchainv1alpha1.Workspace { + // TODO right now we get SpaceCreatorLabelKey but should get owner from Space once it's implemented + ownerName := space.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] - wsOptions := []commonproxy.WorkspaceOption{ - commonproxy.WithNamespaces(space.Status.ProvisionedNamespaces), - commonproxy.WithOwner(ownerName), - commonproxy.WithRole(spaceBinding.Spec.SpaceRole), - commonproxy.WithObjectMetaFrom(space.ObjectMeta), - } - // set the workspace type to "home" to indicate it is the user's home space - // TODO set home type based on UserSignup.Status.HomeSpace once it's implemented - if ownerName == signupName { - wsOptions = append(wsOptions, commonproxy.WithType("home")) - } + wsOptions := []commonproxy.WorkspaceOption{ + commonproxy.WithNamespaces(space.Status.ProvisionedNamespaces), + commonproxy.WithOwner(ownerName), + commonproxy.WithRole(spaceBinding.Spec.SpaceRole), + commonproxy.WithObjectMetaFrom(space.ObjectMeta), + } + // set the workspace type to "home" to indicate it is the user's home space + // TODO set home type based on UserSignup.Status.HomeSpace once it's implemented + if ownerName == signupName { + wsOptions = append(wsOptions, commonproxy.WithType("home")) + } + wsOptions = append(wsOptions, wsAdditionalOptions...) - workspace := commonproxy.NewWorkspace(spaceName, wsOptions...) - workspaces = append(workspaces, *workspace) + workspace := commonproxy.NewWorkspace(space.GetName(), wsOptions...) + return workspace +} + +func (s *SpaceLister) getSpace(spaceBinding *toolchainv1alpha1.SpaceBinding) (*toolchainv1alpha1.Space, error) { + spaceName := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey] + if spaceName == "" { // space may not be initialized + // log error and continue so that the api behaves in a best effort manner + return nil, fmt.Errorf("spacebinding has no '%s' label", toolchainv1alpha1.SpaceBindingSpaceLabelKey) } - return workspaces + return s.GetInformerServiceFunc().GetSpace(spaceName) +} + +func getRolesFromNSTemplateTier(nstemplatetier *toolchainv1alpha1.NSTemplateTier) []string { + roles := make([]string, len(nstemplatetier.Spec.SpaceRoles)) + i := 0 + for k := range nstemplatetier.Spec.SpaceRoles { + roles[i] = k + i++ + } + sort.Strings(roles) + return roles } func listWorkspaceResponse(ctx echo.Context, workspaces []toolchainv1alpha1.Workspace) error { @@ -159,7 +250,7 @@ func listWorkspaceResponse(ctx echo.Context, workspaces []toolchainv1alpha1.Work return json.NewEncoder(ctx.Response().Writer).Encode(workspaceList) } -func getWorkspaceResponse(ctx echo.Context, workspace toolchainv1alpha1.Workspace) error { +func getWorkspaceResponse(ctx echo.Context, workspace *toolchainv1alpha1.Workspace) error { ctx.Response().Writer.Header().Set("Content-Type", "application/json") ctx.Response().Writer.WriteHeader(http.StatusOK) return json.NewEncoder(ctx.Response().Writer).Encode(workspace) diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index f18ee370..ad791f58 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/gin-gonic/gin" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/codeready-toolchain/registration-service/pkg/application/service" "github.com/codeready-toolchain/registration-service/pkg/configuration" @@ -41,6 +42,10 @@ func TestHandleSpaceListRequest(t *testing.T) { newSignup("racinglover", "racing.lover", false), ) + fakeNsTemplateTierService := fake.NewNSTemplateTierService( + newBase1NSTemplateTier(), + ) + t.Run("HandleSpaceListRequest", func(t *testing.T) { // given @@ -63,13 +68,14 @@ func TestHandleSpaceListRequest(t *testing.T) { ) tests := map[string]struct { - username string - expectedWs []toolchainv1alpha1.Workspace - expectedErr string - expectedErrCode int - expectedWorkspace string - overrideSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) - overrideInformerFunc func() service.InformerService + username string + expectedWs []toolchainv1alpha1.Workspace + expectedErr string + expectedErrCode int + expectedWorkspace string + overrideSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) + overrideNSTemplateTierProvider func(ctx *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) + overrideInformerFunc func() service.InformerService }{ "dancelover lists spaces": { username: "dance.lover", @@ -89,7 +95,12 @@ func TestHandleSpaceListRequest(t *testing.T) { "dancelover gets dancelover space": { username: "dance.lover", expectedWs: []toolchainv1alpha1.Workspace{ - workspaceFor(t, fakeClient, "dancelover", "admin", true), + workspaceFor(t, fakeClient, "dancelover", "admin", true, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + }, + ), + ), }, expectedErr: "", expectedWorkspace: "dancelover", @@ -97,7 +108,10 @@ func TestHandleSpaceListRequest(t *testing.T) { "dancelover gets movielover space": { username: "dance.lover", expectedWs: []toolchainv1alpha1.Workspace{ - workspaceFor(t, fakeClient, "movielover", "other", false), + workspaceFor(t, fakeClient, "movielover", "other", false, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + })), }, expectedErr: "", expectedWorkspace: "movielover", @@ -105,7 +119,10 @@ func TestHandleSpaceListRequest(t *testing.T) { "movielover gets movielover space": { username: "movie.lover", expectedWs: []toolchainv1alpha1.Workspace{ - workspaceFor(t, fakeClient, "movielover", "admin", true), + workspaceFor(t, fakeClient, "movielover", "admin", true, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + })), }, expectedErr: "", expectedWorkspace: "movielover", @@ -120,7 +137,10 @@ func TestHandleSpaceListRequest(t *testing.T) { "signup not ready yet": { username: "movie.lover", expectedWs: []toolchainv1alpha1.Workspace{ - workspaceFor(t, fakeClient, "movielover", "admin", true), + workspaceFor(t, fakeClient, "movielover", "admin", true, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + })), }, expectedErr: "", expectedWorkspace: "movielover", @@ -165,6 +185,16 @@ func TestHandleSpaceListRequest(t *testing.T) { return nil, fmt.Errorf("signup error") }, }, + "get nstemplatetier error": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "nstemplatetier error", + expectedErrCode: 500, + overrideNSTemplateTierProvider: func(ctx *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { + return nil, fmt.Errorf("nstemplatetier error") + }, + expectedWorkspace: "dancelover", + }, } for k, tc := range tests { @@ -175,6 +205,11 @@ func TestHandleSpaceListRequest(t *testing.T) { signupProvider = tc.overrideSignupFunc } + nsTemplateTierProvider := fakeNsTemplateTierService.GetNSTemplateTierFromInformer + if tc.overrideNSTemplateTierProvider != nil { + nsTemplateTierProvider = tc.overrideNSTemplateTierProvider + } + informerFunc := getFakeInformerService(fakeClient) if tc.overrideInformerFunc != nil { informerFunc = tc.overrideInformerFunc @@ -183,6 +218,7 @@ func TestHandleSpaceListRequest(t *testing.T) { s := &handlers.SpaceLister{ GetSignupFunc: signupProvider, GetInformerServiceFunc: informerFunc, + GetNSTemplateTierFunc: nsTemplateTierProvider, } e := echo.New() @@ -231,6 +267,36 @@ func TestHandleSpaceListRequest(t *testing.T) { }) } +func newBase1NSTemplateTier() fake.NSTemplateTierDef { + return fake.NSTemplateTier("base1ns", &toolchainv1alpha1.NSTemplateTier{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "toolchain-host-operator", + Name: "base1ns", + }, + Spec: toolchainv1alpha1.NSTemplateTierSpec{ + ClusterResources: &toolchainv1alpha1.NSTemplateTierClusterResources{ + TemplateRef: "basic-clusterresources-123456new", + }, + Namespaces: []toolchainv1alpha1.NSTemplateTierNamespace{ + { + TemplateRef: "basic-dev-123456new", + }, + { + TemplateRef: "basic-stage-123456new", + }, + }, + SpaceRoles: map[string]toolchainv1alpha1.NSTemplateTierSpaceRole{ + "admin": { + TemplateRef: "basic-admin-123456new", + }, + "viewer": { + TemplateRef: "basic-viewer-123456new", + }, + }, + }, + }) +} + func newSignup(signupName, username string, ready bool) fake.SignupDef { compliantUsername := signupName if !ready { @@ -302,14 +368,14 @@ func decodeResponseToWorkspaceList(data []byte) (*toolchainv1alpha1.WorkspaceLis return obj, nil } -func workspaceFor(t *testing.T, fakeClient client.Client, name, role string, isHomeWorkspace bool) toolchainv1alpha1.Workspace { +func workspaceFor(t *testing.T, fakeClient client.Client, name, role string, isHomeWorkspace bool, additionalWSOptions ...commonproxy.WorkspaceOption) toolchainv1alpha1.Workspace { // get the space for the user space := &toolchainv1alpha1.Space{} err := fakeClient.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: configuration.Namespace()}, space) require.NoError(t, err) // create the workspace based on the space - ws := commonproxy.NewWorkspace(name, + commonWSoptions := []commonproxy.WorkspaceOption{ commonproxy.WithObjectMetaFrom(space.ObjectMeta), commonproxy.WithNamespaces([]toolchainv1alpha1.SpaceNamespace{ { @@ -322,6 +388,9 @@ func workspaceFor(t *testing.T, fakeClient client.Client, name, role string, isH }), commonproxy.WithOwner(name), commonproxy.WithRole(role), + } + ws := commonproxy.NewWorkspace(name, + append(commonWSoptions, additionalWSOptions...)..., ) // if the user is the same as the one who created the workspace, then expect type should be "home" if isHomeWorkspace { diff --git a/test/fake/informer.go b/test/fake/informer.go index 1a6d952c..e03437cf 100644 --- a/test/fake/informer.go +++ b/test/fake/informer.go @@ -19,6 +19,7 @@ type Informer struct { GetUserSignupFunc func(name string) (*toolchainv1alpha1.UserSignup, error) ListSpaceBindingFunc func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) GetProxyPluginConfigFunc func(name string) (*toolchainv1alpha1.ProxyPlugin, error) + GetNSTemplateTierFunc func(name string) (*toolchainv1alpha1.NSTemplateTier, error) } func (f Informer) GetProxyPluginConfig(name string) (*toolchainv1alpha1.ProxyPlugin, error) { @@ -63,6 +64,13 @@ func (f Informer) ListSpaceBindings(req ...labels.Requirement) ([]toolchainv1alp panic("not supposed to call ListSpaceBindings") } +func (f Informer) GetNSTemplateTier(tier string) (*toolchainv1alpha1.NSTemplateTier, error) { + if f.GetNSTemplateTierFunc != nil { + return f.GetNSTemplateTierFunc(tier) + } + panic("not supposed to call GetNSTemplateTierFunc") +} + func NewSpace(name, targetCluster, compliantUserName string) *toolchainv1alpha1.Space { space := &toolchainv1alpha1.Space{ ObjectMeta: metav1.ObjectMeta{ diff --git a/test/fake/proxy.go b/test/fake/proxy.go index bad15e29..92d99d6b 100644 --- a/test/fake/proxy.go +++ b/test/fake/proxy.go @@ -49,6 +49,56 @@ func (f *fakeClusterService) GetClusterAccess(userID, _, _, _ string) (*access.C return f.fakeApp.Accesses[userID], f.fakeApp.Err } +type NSTemplateTierDef func() (string, *toolchainv1alpha1.NSTemplateTier) + +func NSTemplateTier(identifier string, nsTemplateTier *toolchainv1alpha1.NSTemplateTier) NSTemplateTierDef { + return func() (string, *toolchainv1alpha1.NSTemplateTier) { + return identifier, nsTemplateTier + } +} + +func NewNSTemplateTierService(nsTemplateTierDefs ...NSTemplateTierDef) *NSTemplateTierService { + sc := newFakeNSTemplateTierService() + for _, nsTemplateTierDef := range nsTemplateTierDefs { + identifier, nstemplatetier := nsTemplateTierDef() + sc.addNSTemplateTier(identifier, nstemplatetier) + } + return sc +} + +func newFakeNSTemplateTierService() *NSTemplateTierService { + f := &NSTemplateTierService{} + f.MockGetNsTemplateTier = f.DefaultMockGetNSTemplateTier() + return f +} + +func (n *NSTemplateTierService) addNSTemplateTier(identifier string, nsTemplateTier *toolchainv1alpha1.NSTemplateTier) *NSTemplateTierService { + if n.tiers == nil { + n.tiers = make(map[string]*toolchainv1alpha1.NSTemplateTier) + } + n.tiers[identifier] = nsTemplateTier + return n +} + +type NSTemplateTierService struct { + MockGetNsTemplateTier func(tierName string) (*toolchainv1alpha1.NSTemplateTier, error) + tiers map[string]*toolchainv1alpha1.NSTemplateTier +} + +func (n *NSTemplateTierService) DefaultMockGetNSTemplateTier() func(tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { + return func(tierName string) (nsTemplateTier *toolchainv1alpha1.NSTemplateTier, e error) { + tier := n.tiers[tierName] + if tier != nil { + return tier, nil + } + return nil, nil + } +} + +func (n *NSTemplateTierService) GetNSTemplateTierFromInformer(_ *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { + return n.MockGetNsTemplateTier(tierName) +} + type SignupDef func() (string, *signup.Signup) func Signup(identifier string, userSignup *signup.Signup) SignupDef { From 9e08ece373d0601c15389bde6145141277d20722 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 20 Sep 2023 18:55:53 +0200 Subject: [PATCH 02/26] replace toolchain-common --- go.mod | 13 +------------ go.sum | 35 ++--------------------------------- 2 files changed, 3 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index 9e773ca9..8c167814 100644 --- a/go.mod +++ b/go.mod @@ -49,17 +49,13 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fatih/color v1.12.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect - github.com/gobuffalo/flect v0.2.5 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-github/v52 v52.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.1 // indirect github.com/gorilla/mux v1.8.0 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect @@ -68,22 +64,15 @@ require ( github.com/lestrrat-go/option v1.0.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/migueleliasweb/go-github-mock v0.0.18 // indirect - github.com/spf13/cobra v1.4.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/tools v0.6.0 // indirect google.golang.org/api v0.114.0 // indirect google.golang.org/genproto v0.0.0-20230320184635-7606e756e683 // indirect google.golang.org/grpc v1.53.0 // indirect - k8s.io/apiextensions-apiserver v0.25.0 // indirect - k8s.io/code-generator v0.25.0 // indirect - k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect - sigs.k8s.io/controller-tools v0.10.0 // indirect ) require ( @@ -148,4 +137,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/codeready-toolchain/toolchain-common => /Users/fmuntean/go/src/github.com/codeready-toolchain/toolchain-common \ No newline at end of file +replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20230920161730-cbaf858a894d diff --git a/go.sum b/go.sum index e27185bd..e4b4c49f 100644 --- a/go.sum +++ b/go.sum @@ -106,15 +106,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/codeready-toolchain/api v0.0.0-20230818091928-38277763fa2d h1:aV4QEU4SOOqNJcsIaziX0ZHYtgxMpnBD9O5iqn3WZzs= -github.com/codeready-toolchain/api v0.0.0-20230818091928-38277763fa2d/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= -github.com/codeready-toolchain/api v0.0.0-20230912073725-4ae0201b4630 h1:Z281nLD0OLfdzbUq2tUK5/B6d2OX1hPg5oFGZSJM4RQ= -github.com/codeready-toolchain/api v0.0.0-20230912073725-4ae0201b4630/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33 h1:hxXfcFq2JgFISVxrkISg8m9DZMzpcPWRjPspx3M3Sxo= github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= -github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3 h1:zPxv/JJRZsXS+OVgsrF1egFlTi45DXJ8MTPi50meujI= -github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3/go.mod h1:vtUfWOJBDxQP1DtcIoxfjI5heBGcT8D+C8ux+PLouyg= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -139,8 +132,6 @@ github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCv github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= @@ -157,15 +148,12 @@ github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwv github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= -github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= @@ -194,8 +182,6 @@ github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GO github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/gobuffalo/flect v0.2.5 h1:H6vvsv2an0lalEaCDRThvtBfmg44W/QHXBCYUXf/6S4= -github.com/gobuffalo/flect v0.2.5/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -287,7 +273,6 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -309,8 +294,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -371,7 +354,6 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215 h1:hDa3vAq/Zo5gjfJ46XMsGFbH+hTizpR4fUzQCk2nxgk= github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215/go.mod h1:LH+NgPY9AJpDfqAFtzyer01N9MYNsAKUf3DC9DV1xIY= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -381,6 +363,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/mfrancisc/toolchain-common v0.0.0-20230920161730-cbaf858a894d h1:IjiA1gvkGR7fZDuelLrOS80JobW7FZaeIpGRu8s1lRw= +github.com/mfrancisc/toolchain-common v0.0.0-20230920161730-cbaf858a894d/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -422,11 +406,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -537,7 +518,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -747,7 +727,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -768,7 +747,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -981,21 +959,15 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0= k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= k8s.io/apiextensions-apiserver v0.25.0 h1:CJ9zlyXAbq0FIW8CD7HHyozCMBpDSiH7EdrSTCZcZFY= -k8s.io/apiextensions-apiserver v0.25.0/go.mod h1:3pAjZiN4zw7R8aZC5gR0y3/vCkGlAjCazcg1me8iB/E= k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU= k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0= k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= -k8s.io/code-generator v0.25.0 h1:QP8fJuXu882ztf6dsqJsso/Btm94pMd68TAZC1rE6KI= -k8s.io/code-generator v0.25.0/go.mod h1:B6jZgI3DvDFAualltPitbYMQ74NjaCFxum3YeKZZ+3w= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= @@ -1008,12 +980,9 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= -sigs.k8s.io/controller-tools v0.10.0 h1:0L5DTDTFB67jm9DkfrONgTGmfc/zYow0ZaHyppizU2U= -sigs.k8s.io/controller-tools v0.10.0/go.mod h1:uvr0EW6IsprfB0jpQq6evtKy+hHyHCXNfdWI5ONPx94= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= From b6a4d8fdb53e655f2f236ec15268c8093fbd6420 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 20 Sep 2023 19:18:36 +0200 Subject: [PATCH 03/26] update common --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8c167814..8b39609f 100644 --- a/go.mod +++ b/go.mod @@ -137,4 +137,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20230920161730-cbaf858a894d +replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20230920171626-876ba9b0d3c4 diff --git a/go.sum b/go.sum index e4b4c49f..431e894e 100644 --- a/go.sum +++ b/go.sum @@ -363,8 +363,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/mfrancisc/toolchain-common v0.0.0-20230920161730-cbaf858a894d h1:IjiA1gvkGR7fZDuelLrOS80JobW7FZaeIpGRu8s1lRw= -github.com/mfrancisc/toolchain-common v0.0.0-20230920161730-cbaf858a894d/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= +github.com/mfrancisc/toolchain-common v0.0.0-20230920171626-876ba9b0d3c4 h1:XIw5csoJ0Ydw0Aoeg9heZv031pujrDgeSv9S5h3OUEE= +github.com/mfrancisc/toolchain-common v0.0.0-20230920171626-876ba9b0d3c4/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= From 44eee9d916b33bbe74639466f4849259954060ea Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 20 Sep 2023 19:36:45 +0200 Subject: [PATCH 04/26] fix linter --- pkg/proxy/handlers/spacelister.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index c8c29092..4d12879a 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -56,10 +56,9 @@ func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) - } else { - // return empty workspace list - return listWorkspaceResponse(ctx, []toolchainv1alpha1.Workspace{}) } + // return empty workspace list + return listWorkspaceResponse(ctx, []toolchainv1alpha1.Workspace{}) } // get specific workspace @@ -179,17 +178,18 @@ func (s *SpaceLister) listSpaceBindingForUserAndSpace(ctx echo.Context, murName return &spaceBindings[0], nil } -func (s *SpaceLister) workspacesFromSpaceBindings(signupName string, spaceBindings []toolchainv1alpha1.SpaceBinding, wsAdditionalOptions ...commonproxy.WorkspaceOption) []toolchainv1alpha1.Workspace { +func (s *SpaceLister) workspacesFromSpaceBindings(signupName string, spaceBindings []toolchainv1alpha1.SpaceBinding) []toolchainv1alpha1.Workspace { workspaces := []toolchainv1alpha1.Workspace{} - for _, spaceBinding := range spaceBindings { - space, err := s.getSpace(&spaceBinding) + for i := range spaceBindings { + spacebinding := &spaceBindings[i] + space, err := s.getSpace(spacebinding) if err != nil { // log error and continue so that the api behaves in a best effort manner // ie. if a space isn't listed something went wrong but we still want to return the other spaces if possible - log.Errorf(nil, err, "unable to get space", "space", spaceBinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey]) + log.Errorf(nil, err, "unable to get space", "space", spacebinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey]) continue } - workspace := createCommonWorkspace(signupName, space, &spaceBinding) + workspace := createCommonWorkspace(signupName, space, spacebinding) workspaces = append(workspaces, *workspace) } return workspaces From c3639a39e3a2d367253f90650751c5581f7da4ac Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 20 Sep 2023 21:15:43 +0200 Subject: [PATCH 05/26] add nstemplatetier to informer start --- pkg/informers/informers.go | 6 ++++++ pkg/kubeclient/resources/names.go | 1 + 2 files changed, 7 insertions(+) diff --git a/pkg/informers/informers.go b/pkg/informers/informers.go index 92dccced..6435788d 100644 --- a/pkg/informers/informers.go +++ b/pkg/informers/informers.go @@ -65,6 +65,11 @@ func StartInformer(cfg *rest.Config) (*Informer, chan struct{}, error) { informer.ProxyPluginConfig = proxyPluginInformer.Lister() proxyPluginConfigInformer := proxyPluginInformer.Informer() + // NSTemplateTier plugins + genericNSTemplateTierInformer := factory.ForResource(schema.GroupVersionResource{Group: "toolchain.dev.openshift.com", Version: "v1alpha1", Resource: resources.NSTemplateTierPlural}) + informer.NSTemplateTier = genericNSTemplateTierInformer.Lister() + nsTemplateTierInformer := genericNSTemplateTierInformer.Informer() + stopper := make(chan struct{}) log.Info(nil, "Starting proxy cache informers") @@ -77,6 +82,7 @@ func StartInformer(cfg *rest.Config) (*Informer, chan struct{}, error) { toolchainstatusInformer.HasSynced, userSignupInformer.HasSynced, proxyPluginConfigInformer.HasSynced, + nsTemplateTierInformer.HasSynced, ) { err := fmt.Errorf("timed out waiting for caches to sync") log.Error(nil, err, "Failed to create informers") diff --git a/pkg/kubeclient/resources/names.go b/pkg/kubeclient/resources/names.go index e9e7764b..1995fd56 100644 --- a/pkg/kubeclient/resources/names.go +++ b/pkg/kubeclient/resources/names.go @@ -8,4 +8,5 @@ const ( ToolchainStatusPlural = "toolchainstatuses" ToolchainStatusName = "toolchain-status" ProxyPluginsPlural = "proxyplugins" + NSTemplateTierPlural = "nstemplatetiers" ) From f333b61b0707b10df810c599a02632cf5fc839a9 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Thu, 21 Sep 2023 15:14:28 +0200 Subject: [PATCH 06/26] create HandleSpaceGetRequest handler in proxy --- deploy/registration-service.yaml | 6 + pkg/proxy/handlers/spacelister.go | 54 +++--- pkg/proxy/handlers/spacelister_test.go | 232 ++++++++++++++----------- pkg/proxy/proxy.go | 2 +- 4 files changed, 172 insertions(+), 122 deletions(-) diff --git a/deploy/registration-service.yaml b/deploy/registration-service.yaml index aaa123eb..c2a08f9f 100644 --- a/deploy/registration-service.yaml +++ b/deploy/registration-service.yaml @@ -1,3 +1,8 @@ +#################################################################################################### +# NOTE: after modifying this file remember to: +# 1) run make copy-reg-service-template (which will update the copy of this file at : https://github.com/codeready-toolchain/host-operator/blob/master/deploy/registration-service/registration-service.yaml) +# 2) open a PR in host-operator with that change before merging the changes in registration-service +#################################################################################################### apiVersion: template.openshift.io/v1 kind: Template metadata: @@ -38,6 +43,7 @@ objects: - toolchainconfigs - toolchainstatuses - proxyplugins + - nstemplatetiers verbs: - get - list diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 4d12879a..cd5b996f 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -38,11 +38,8 @@ func NewSpaceLister(app application.Application) *SpaceLister { } func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { - userID, _ := ctx.Get(context.SubKey).(string) username, _ := ctx.Get(context.UsernameKey).(string) - workspaceName := ctx.Param("workspace") - doGetWorkspace := len(workspaceName) > 0 userSignup, err := s.GetSignupFunc(nil, userID, username, false) if err != nil { @@ -51,30 +48,10 @@ func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { } if userSignup == nil || userSignup.CompliantUsername == "" { // account exists but the compliant username is not set yet, meaning it has not been fully provisioned yet - if doGetWorkspace { - // return not found response when specific workspace request was issued - r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} - return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) - - } // return empty workspace list return listWorkspaceResponse(ctx, []toolchainv1alpha1.Workspace{}) } - // get specific workspace - if doGetWorkspace { - workspace, err := s.GetUserWorkspace(ctx, userSignup) - if err != nil { - return errorResponse(ctx, apierrors.NewInternalError(err)) - } - if workspace == nil { - // not found - r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} - return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) - } - return getWorkspaceResponse(ctx, workspace) - } - // list all user workspaces workspaces, err := s.ListUserWorkspaces(ctx) if err != nil { @@ -83,6 +60,37 @@ func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { return listWorkspaceResponse(ctx, workspaces) } +func (s *SpaceLister) HandleSpaceGetRequest(ctx echo.Context) error { + userID, _ := ctx.Get(context.SubKey).(string) + username, _ := ctx.Get(context.UsernameKey).(string) + workspaceName := ctx.Param("workspace") + + userSignup, err := s.GetSignupFunc(nil, userID, username, false) + if err != nil { + ctx.Logger().Error(errs.Wrap(err, "error retrieving userSignup")) + return errorResponse(ctx, apierrors.NewInternalError(err)) + } + if userSignup == nil || userSignup.CompliantUsername == "" { + // account exists but the compliant username is not set yet, meaning it has not been fully provisioned yet + // return not found response when specific workspace request was issued + r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} + return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) + + } + + // get specific workspace + workspace, err := s.GetUserWorkspace(ctx, userSignup) + if err != nil { + return errorResponse(ctx, apierrors.NewInternalError(err)) + } + if workspace == nil { + // not found + r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} + return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) + } + return getWorkspaceResponse(ctx, workspace) +} + func (s *SpaceLister) GetUserWorkspace(ctx echo.Context, signup *signup.Signup) (*toolchainv1alpha1.Workspace, error) { murName := signup.CompliantUsername spaceBinding, err := s.listSpaceBindingForUserAndSpace(ctx, murName) diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index ad791f58..614f2a75 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" ) -func TestHandleSpaceListRequest(t *testing.T) { +func TestSpaceLister(t *testing.T) { fakeSignupService := fake.NewSignupService( newSignup("dancelover", "dance.lover", true), @@ -46,36 +46,34 @@ func TestHandleSpaceListRequest(t *testing.T) { newBase1NSTemplateTier(), ) - t.Run("HandleSpaceListRequest", func(t *testing.T) { - // given - - // space that is not provisioned yet - spaceNotProvisionedYet := fake.NewSpace("pandalover", "member-2", "pandalover") - spaceNotProvisionedYet.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] = "" + // space that is not provisioned yet + spaceNotProvisionedYet := fake.NewSpace("pandalover", "member-2", "pandalover") + spaceNotProvisionedYet.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] = "" - fakeClient := initFakeClient(t, - // spaces - fake.NewSpace("dancelover", "member-1", "dancelover"), - fake.NewSpace("movielover", "member-1", "movielover"), - fake.NewSpace("racinglover", "member-2", "racinglover"), - spaceNotProvisionedYet, + fakeClient := initFakeClient(t, + // spaces + fake.NewSpace("dancelover", "member-1", "dancelover"), + fake.NewSpace("movielover", "member-1", "movielover"), + fake.NewSpace("racinglover", "member-2", "racinglover"), + spaceNotProvisionedYet, - //spacebindings - fake.NewSpaceBinding("dancer-sb1", "dancelover", "dancelover", "admin"), - fake.NewSpaceBinding("dancer-sb2", "dancelover", "movielover", "other"), - fake.NewSpaceBinding("moviegoer-sb", "movielover", "movielover", "admin"), - fake.NewSpaceBinding("racer-sb", "racinglover", "racinglover", "admin"), - ) + //spacebindings + fake.NewSpaceBinding("dancer-sb1", "dancelover", "dancelover", "admin"), + fake.NewSpaceBinding("dancer-sb2", "dancelover", "movielover", "other"), + fake.NewSpaceBinding("moviegoer-sb", "movielover", "movielover", "admin"), + fake.NewSpaceBinding("racer-sb", "racinglover", "racinglover", "admin"), + ) + t.Run("HandleSpaceListRequest", func(t *testing.T) { + // given tests := map[string]struct { - username string - expectedWs []toolchainv1alpha1.Workspace - expectedErr string - expectedErrCode int - expectedWorkspace string - overrideSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) - overrideNSTemplateTierProvider func(ctx *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) - overrideInformerFunc func() service.InformerService + username string + expectedWs []toolchainv1alpha1.Workspace + expectedErr string + expectedErrCode int + expectedWorkspace string + overrideSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) + overrideInformerFunc func() service.InformerService }{ "dancelover lists spaces": { username: "dance.lover", @@ -92,6 +90,105 @@ func TestHandleSpaceListRequest(t *testing.T) { }, expectedErr: "", }, + "signup has no compliant username set": { + username: "racing.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "", + expectedErrCode: 200, + }, + "space not initialized yet": { + username: "panda.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "", + expectedErrCode: 200, + }, + "no spaces found": { + username: "user.nospace", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "", + expectedErrCode: 200, + }, + "informer error": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "list spacebindings error", + expectedErrCode: 500, + overrideInformerFunc: func() service.InformerService { + inf := fake.NewFakeInformer() + inf.ListSpaceBindingFunc = func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { + return nil, fmt.Errorf("list spacebindings error") + } + return inf + }, + }, + "get signup error": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "signup error", + expectedErrCode: 500, + overrideSignupFunc: func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) { + return nil, fmt.Errorf("signup error") + }, + }, + } + + for k, tc := range tests { + t.Run(k, func(t *testing.T) { + // given + signupProvider := fakeSignupService.GetSignupFromInformer + if tc.overrideSignupFunc != nil { + signupProvider = tc.overrideSignupFunc + } + + informerFunc := getFakeInformerService(fakeClient) + if tc.overrideInformerFunc != nil { + informerFunc = tc.overrideInformerFunc + } + + s := &handlers.SpaceLister{ + GetSignupFunc: signupProvider, + GetInformerServiceFunc: informerFunc, + } + + e := echo.New() + req := httptest.NewRequest(http.MethodGet, "/", strings.NewReader("")) + rec := httptest.NewRecorder() + ctx := e.NewContext(req, rec) + ctx.Set(rcontext.UsernameKey, tc.username) + + // when + err := s.HandleSpaceListRequest(ctx) + + // then + if tc.expectedErr != "" { + // error case + require.Equal(t, tc.expectedErrCode, rec.Code) + require.Contains(t, rec.Body.String(), tc.expectedErr) + } else { + require.NoError(t, err) + // list workspace case + workspaceList, decodeErr := decodeResponseToWorkspaceList(rec.Body.Bytes()) + require.NoError(t, decodeErr) + require.Equal(t, len(tc.expectedWs), len(workspaceList.Items)) + for i := range tc.expectedWs { + assert.Equal(t, tc.expectedWs[i].Name, workspaceList.Items[i].Name) + assert.Equal(t, tc.expectedWs[i].Status, workspaceList.Items[i].Status) + } + } + }) + } + }) + + t.Run("HandleSpaceGetRequest", func(t *testing.T) { + // given + tests := map[string]struct { + username string + expectedWs []toolchainv1alpha1.Workspace + expectedErr string + expectedErrCode int + expectedWorkspace string + overrideNSTemplateTierProvider func(ctx *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) + }{ "dancelover gets dancelover space": { username: "dance.lover", expectedWs: []toolchainv1alpha1.Workspace{ @@ -145,46 +242,6 @@ func TestHandleSpaceListRequest(t *testing.T) { expectedErr: "", expectedWorkspace: "movielover", }, - "signup has no compliant username set": { - username: "racing.lover", - expectedWs: []toolchainv1alpha1.Workspace{}, - expectedErr: "", - expectedErrCode: 200, - }, - "space not initialized yet": { - username: "panda.lover", - expectedWs: []toolchainv1alpha1.Workspace{}, - expectedErr: "", - expectedErrCode: 200, - }, - "no spaces found": { - username: "user.nospace", - expectedWs: []toolchainv1alpha1.Workspace{}, - expectedErr: "", - expectedErrCode: 200, - }, - "informer error": { - username: "dance.lover", - expectedWs: []toolchainv1alpha1.Workspace{}, - expectedErr: "list spacebindings error", - expectedErrCode: 500, - overrideInformerFunc: func() service.InformerService { - inf := fake.NewFakeInformer() - inf.ListSpaceBindingFunc = func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { - return nil, fmt.Errorf("list spacebindings error") - } - return inf - }, - }, - "get signup error": { - username: "dance.lover", - expectedWs: []toolchainv1alpha1.Workspace{}, - expectedErr: "signup error", - expectedErrCode: 500, - overrideSignupFunc: func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) { - return nil, fmt.Errorf("signup error") - }, - }, "get nstemplatetier error": { username: "dance.lover", expectedWs: []toolchainv1alpha1.Workspace{}, @@ -201,9 +258,6 @@ func TestHandleSpaceListRequest(t *testing.T) { t.Run(k, func(t *testing.T) { // given signupProvider := fakeSignupService.GetSignupFromInformer - if tc.overrideSignupFunc != nil { - signupProvider = tc.overrideSignupFunc - } nsTemplateTierProvider := fakeNsTemplateTierService.GetNSTemplateTierFromInformer if tc.overrideNSTemplateTierProvider != nil { @@ -211,10 +265,6 @@ func TestHandleSpaceListRequest(t *testing.T) { } informerFunc := getFakeInformerService(fakeClient) - if tc.overrideInformerFunc != nil { - informerFunc = tc.overrideInformerFunc - } - s := &handlers.SpaceLister{ GetSignupFunc: signupProvider, GetInformerServiceFunc: informerFunc, @@ -226,14 +276,11 @@ func TestHandleSpaceListRequest(t *testing.T) { rec := httptest.NewRecorder() ctx := e.NewContext(req, rec) ctx.Set(rcontext.UsernameKey, tc.username) - - if tc.expectedWorkspace != "" { - ctx.SetParamNames("workspace") - ctx.SetParamValues(tc.expectedWorkspace) - } + ctx.SetParamNames("workspace") + ctx.SetParamValues(tc.expectedWorkspace) // when - err := s.HandleSpaceListRequest(ctx) + err := s.HandleSpaceGetRequest(ctx) // then if tc.expectedErr != "" { @@ -242,24 +289,13 @@ func TestHandleSpaceListRequest(t *testing.T) { require.Contains(t, rec.Body.String(), tc.expectedErr) } else { require.NoError(t, err) - if tc.expectedWorkspace != "" { - // get workspace case - workspace, decodeErr := decodeResponseToWorkspace(rec.Body.Bytes()) - require.NoError(t, decodeErr) - require.Equal(t, 1, len(tc.expectedWs), "test case should have exactly one expected item since it's a get request") - for i := range tc.expectedWs { - assert.Equal(t, tc.expectedWs[i].Name, workspace.Name) - assert.Equal(t, tc.expectedWs[i].Status, workspace.Status) - } - } else { - // list workspace case - workspaceList, decodeErr := decodeResponseToWorkspaceList(rec.Body.Bytes()) - require.NoError(t, decodeErr) - require.Equal(t, len(tc.expectedWs), len(workspaceList.Items)) - for i := range tc.expectedWs { - assert.Equal(t, tc.expectedWs[i].Name, workspaceList.Items[i].Name) - assert.Equal(t, tc.expectedWs[i].Status, workspaceList.Items[i].Status) - } + // get workspace case + workspace, decodeErr := decodeResponseToWorkspace(rec.Body.Bytes()) + require.NoError(t, decodeErr) + require.Equal(t, 1, len(tc.expectedWs), "test case should have exactly one expected item since it's a get request") + for i := range tc.expectedWs { + assert.Equal(t, tc.expectedWs[i].Name, workspace.Name) + assert.Equal(t, tc.expectedWs[i].Status, workspace.Status) } } }) diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index 46da7962..34920fbf 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -126,7 +126,7 @@ func (p *Proxy) StartProxy() *http.Server { // routes wg := router.Group("/apis/toolchain.dev.openshift.com/v1alpha1/workspaces") - wg.GET("/:workspace", p.spaceLister.HandleSpaceListRequest) + wg.GET("/:workspace", p.spaceLister.HandleSpaceGetRequest) wg.GET("", p.spaceLister.HandleSpaceListRequest) router.GET(proxyHealthEndpoint, p.health) From 3eeb8fd8685e277966ec9c771c7d654dd159576a Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Thu, 21 Sep 2023 18:01:51 +0200 Subject: [PATCH 07/26] add notes for modifying registration-service.yaml --- deploy/README.md | 8 ++++++++ deploy/registration-service.yaml | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 deploy/README.md diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 00000000..d5165d89 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,8 @@ +### NOTE for modifying `registration-service.yaml` + +After modifying this file remember to: + +1) run `make copy-reg-service-template` (which will copy this file locally into ../host-operator/deploy/registration-service/registration-service.yaml) +2) open a PR in [host-operator](https://github.com/codeready-toolchain/host-operator) with that change. This PR needs to be merged before merging the changes in registration-service. + +This is required since the actual template used for deploying the registration service is the one present at https://github.com/codeready-toolchain/host-operator/blob/master/deploy/registration-service/registration-service.yaml \ No newline at end of file diff --git a/deploy/registration-service.yaml b/deploy/registration-service.yaml index c2a08f9f..53e49f9e 100644 --- a/deploy/registration-service.yaml +++ b/deploy/registration-service.yaml @@ -1,8 +1,3 @@ -#################################################################################################### -# NOTE: after modifying this file remember to: -# 1) run make copy-reg-service-template (which will update the copy of this file at : https://github.com/codeready-toolchain/host-operator/blob/master/deploy/registration-service/registration-service.yaml) -# 2) open a PR in host-operator with that change before merging the changes in registration-service -#################################################################################################### apiVersion: template.openshift.io/v1 kind: Template metadata: From cc777900878064922e63af340f6e59b82415dc30 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 25 Sep 2023 10:29:39 +0200 Subject: [PATCH 08/26] Update pkg/proxy/handlers/spacelister.go Co-authored-by: Alexey Kazakov --- pkg/proxy/handlers/spacelister.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index cd5b996f..341b97a6 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -235,10 +235,8 @@ func (s *SpaceLister) getSpace(spaceBinding *toolchainv1alpha1.SpaceBinding) (*t func getRolesFromNSTemplateTier(nstemplatetier *toolchainv1alpha1.NSTemplateTier) []string { roles := make([]string, len(nstemplatetier.Spec.SpaceRoles)) - i := 0 - for k := range nstemplatetier.Spec.SpaceRoles { + for i, k := range nstemplatetier.Spec.SpaceRoles { roles[i] = k - i++ } sort.Strings(roles) return roles From e83efa484c4ca06b4053e640407cb188ae1e7fdb Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 25 Sep 2023 10:36:46 +0200 Subject: [PATCH 09/26] update name --- pkg/proxy/handlers/spacelister.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 341b97a6..e7f87172 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -123,7 +123,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context, signup *signup.Signup) } getOnlyWSOptions := commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)) - return createCommonWorkspace(signup.Name, space, spaceBinding, getOnlyWSOptions), nil + return createWorkspaceObject(signup.Name, space, spaceBinding, getOnlyWSOptions), nil } func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1.Workspace, error) { @@ -197,13 +197,13 @@ func (s *SpaceLister) workspacesFromSpaceBindings(signupName string, spaceBindin log.Errorf(nil, err, "unable to get space", "space", spacebinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey]) continue } - workspace := createCommonWorkspace(signupName, space, spacebinding) + workspace := createWorkspaceObject(signupName, space, spacebinding) workspaces = append(workspaces, *workspace) } return workspaces } -func createCommonWorkspace(signupName string, space *toolchainv1alpha1.Space, spaceBinding *toolchainv1alpha1.SpaceBinding, wsAdditionalOptions ...commonproxy.WorkspaceOption) *toolchainv1alpha1.Workspace { +func createWorkspaceObject(signupName string, space *toolchainv1alpha1.Space, spaceBinding *toolchainv1alpha1.SpaceBinding, wsAdditionalOptions ...commonproxy.WorkspaceOption) *toolchainv1alpha1.Workspace { // TODO right now we get SpaceCreatorLabelKey but should get owner from Space once it's implemented ownerName := space.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] @@ -235,8 +235,10 @@ func (s *SpaceLister) getSpace(spaceBinding *toolchainv1alpha1.SpaceBinding) (*t func getRolesFromNSTemplateTier(nstemplatetier *toolchainv1alpha1.NSTemplateTier) []string { roles := make([]string, len(nstemplatetier.Spec.SpaceRoles)) - for i, k := range nstemplatetier.Spec.SpaceRoles { + i := 0 + for k := range nstemplatetier.Spec.SpaceRoles { roles[i] = k + i++ } sort.Strings(roles) return roles From 1305bcf1a4583893eb6a7415ba998abc95fad2d6 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Tue, 26 Sep 2023 16:57:18 +0200 Subject: [PATCH 10/26] use NSTemplateTierFunc from informer --- pkg/proxy/handlers/spacelister.go | 3 +- pkg/proxy/handlers/spacelister_test.go | 88 +++++++++++--------------- test/fake/informer.go | 30 +++++++++ test/fake/proxy.go | 50 --------------- 4 files changed, 68 insertions(+), 103 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index e7f87172..d576443d 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -26,7 +26,6 @@ import ( type SpaceLister struct { GetSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupCompleted bool) (*signup.Signup, error) - GetNSTemplateTierFunc func(ctx *gin.Context, tier string) (*toolchainv1alpha1.NSTemplateTier, error) GetInformerServiceFunc func() service.InformerService } @@ -116,7 +115,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context, signup *signup.Signup) // ------------- // add available roles, this field is populated only for the GET workspace request - nsTemplateTier, err := s.GetNSTemplateTierFunc(nil, space.Spec.TierName) + nsTemplateTier, err := s.GetInformerServiceFunc().GetNSTemplateTier(space.Spec.TierName) if err != nil { ctx.Logger().Error(errs.Wrap(err, "unable to get nstemplatetier")) return nil, err diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index 614f2a75..6168b1ac 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -8,15 +8,13 @@ import ( "strings" "testing" - "github.com/gin-gonic/gin" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/codeready-toolchain/registration-service/pkg/application/service" "github.com/codeready-toolchain/registration-service/pkg/configuration" rcontext "github.com/codeready-toolchain/registration-service/pkg/context" "github.com/codeready-toolchain/registration-service/pkg/proxy/handlers" "github.com/codeready-toolchain/registration-service/pkg/signup" "github.com/codeready-toolchain/registration-service/test/fake" + "github.com/gin-gonic/gin" "sigs.k8s.io/controller-runtime/pkg/client" toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" @@ -42,10 +40,6 @@ func TestSpaceLister(t *testing.T) { newSignup("racinglover", "racing.lover", false), ) - fakeNsTemplateTierService := fake.NewNSTemplateTierService( - newBase1NSTemplateTier(), - ) - // space that is not provisioned yet spaceNotProvisionedYet := fake.NewSpace("pandalover", "member-2", "pandalover") spaceNotProvisionedYet.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] = "" @@ -62,6 +56,9 @@ func TestSpaceLister(t *testing.T) { fake.NewSpaceBinding("dancer-sb2", "dancelover", "movielover", "other"), fake.NewSpaceBinding("moviegoer-sb", "movielover", "movielover", "admin"), fake.NewSpaceBinding("racer-sb", "racinglover", "racinglover", "admin"), + + //nstemplatetier + fake.NewBase1NSTemplateTier(), ) t.Run("HandleSpaceListRequest", func(t *testing.T) { @@ -182,12 +179,12 @@ func TestSpaceLister(t *testing.T) { t.Run("HandleSpaceGetRequest", func(t *testing.T) { // given tests := map[string]struct { - username string - expectedWs []toolchainv1alpha1.Workspace - expectedErr string - expectedErrCode int - expectedWorkspace string - overrideNSTemplateTierProvider func(ctx *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) + username string + expectedWs []toolchainv1alpha1.Workspace + expectedErr string + expectedErrCode int + expectedWorkspace string + overrideInformerFunc func() service.InformerService }{ "dancelover gets dancelover space": { username: "dance.lover", @@ -247,8 +244,11 @@ func TestSpaceLister(t *testing.T) { expectedWs: []toolchainv1alpha1.Workspace{}, expectedErr: "nstemplatetier error", expectedErrCode: 500, - overrideNSTemplateTierProvider: func(ctx *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { - return nil, fmt.Errorf("nstemplatetier error") + overrideInformerFunc: func() service.InformerService { + informerFunc := getFakeInformerService(fakeClient, WithGetNSTemplateTierFunc(func(tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { + return nil, fmt.Errorf("nstemplatetier error") + })) + return informerFunc() }, expectedWorkspace: "dancelover", }, @@ -259,16 +259,14 @@ func TestSpaceLister(t *testing.T) { // given signupProvider := fakeSignupService.GetSignupFromInformer - nsTemplateTierProvider := fakeNsTemplateTierService.GetNSTemplateTierFromInformer - if tc.overrideNSTemplateTierProvider != nil { - nsTemplateTierProvider = tc.overrideNSTemplateTierProvider + informerFunc := getFakeInformerService(fakeClient) + if tc.overrideInformerFunc != nil { + informerFunc = tc.overrideInformerFunc } - informerFunc := getFakeInformerService(fakeClient) s := &handlers.SpaceLister{ GetSignupFunc: signupProvider, GetInformerServiceFunc: informerFunc, - GetNSTemplateTierFunc: nsTemplateTierProvider, } e := echo.New() @@ -303,36 +301,6 @@ func TestSpaceLister(t *testing.T) { }) } -func newBase1NSTemplateTier() fake.NSTemplateTierDef { - return fake.NSTemplateTier("base1ns", &toolchainv1alpha1.NSTemplateTier{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "toolchain-host-operator", - Name: "base1ns", - }, - Spec: toolchainv1alpha1.NSTemplateTierSpec{ - ClusterResources: &toolchainv1alpha1.NSTemplateTierClusterResources{ - TemplateRef: "basic-clusterresources-123456new", - }, - Namespaces: []toolchainv1alpha1.NSTemplateTierNamespace{ - { - TemplateRef: "basic-dev-123456new", - }, - { - TemplateRef: "basic-stage-123456new", - }, - }, - SpaceRoles: map[string]toolchainv1alpha1.NSTemplateTierSpaceRole{ - "admin": { - TemplateRef: "basic-admin-123456new", - }, - "viewer": { - TemplateRef: "basic-viewer-123456new", - }, - }, - }, - }) -} - func newSignup(signupName, username string, ready bool) fake.SignupDef { compliantUsername := signupName if !ready { @@ -351,7 +319,15 @@ func newSignup(signupName, username string, ready bool) fake.SignupDef { return us } -func getFakeInformerService(fakeClient client.Client) func() service.InformerService { +type InformerServiceOptions func(informer *fake.Informer) + +func WithGetNSTemplateTierFunc(getNsTemplateTierFunc func(tier string) (*toolchainv1alpha1.NSTemplateTier, error)) InformerServiceOptions { + return func(informer *fake.Informer) { + informer.GetNSTemplateTierFunc = getNsTemplateTierFunc + } +} + +func getFakeInformerService(fakeClient client.Client, options ...InformerServiceOptions) func() service.InformerService { return func() service.InformerService { inf := fake.NewFakeInformer() @@ -369,6 +345,16 @@ func getFakeInformerService(fakeClient client.Client) func() service.InformerSer err := fakeClient.List(context.TODO(), sbList, labelMatch) return sbList.Items, err } + inf.GetNSTemplateTierFunc = func(tier string) (*toolchainv1alpha1.NSTemplateTier, error) { + nsTemplateTier := &toolchainv1alpha1.NSTemplateTier{} + err := fakeClient.Get(context.TODO(), types.NamespacedName{Name: tier}, nsTemplateTier) + return nsTemplateTier, err + } + + for _, modify := range options { + modify(&inf) + } + return inf } } diff --git a/test/fake/informer.go b/test/fake/informer.go index e03437cf..9f8bd55c 100644 --- a/test/fake/informer.go +++ b/test/fake/informer.go @@ -114,3 +114,33 @@ func NewSpaceBinding(name, murLabelValue, spaceLabelValue, role string) *toolcha }, } } + +func NewBase1NSTemplateTier() *toolchainv1alpha1.NSTemplateTier { + return &toolchainv1alpha1.NSTemplateTier{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: configuration.Namespace(), + Name: "base1ns", + }, + Spec: toolchainv1alpha1.NSTemplateTierSpec{ + ClusterResources: &toolchainv1alpha1.NSTemplateTierClusterResources{ + TemplateRef: "basic-clusterresources-123456new", + }, + Namespaces: []toolchainv1alpha1.NSTemplateTierNamespace{ + { + TemplateRef: "basic-dev-123456new", + }, + { + TemplateRef: "basic-stage-123456new", + }, + }, + SpaceRoles: map[string]toolchainv1alpha1.NSTemplateTierSpaceRole{ + "admin": { + TemplateRef: "basic-admin-123456new", + }, + "viewer": { + TemplateRef: "basic-viewer-123456new", + }, + }, + }, + } +} diff --git a/test/fake/proxy.go b/test/fake/proxy.go index 92d99d6b..bad15e29 100644 --- a/test/fake/proxy.go +++ b/test/fake/proxy.go @@ -49,56 +49,6 @@ func (f *fakeClusterService) GetClusterAccess(userID, _, _, _ string) (*access.C return f.fakeApp.Accesses[userID], f.fakeApp.Err } -type NSTemplateTierDef func() (string, *toolchainv1alpha1.NSTemplateTier) - -func NSTemplateTier(identifier string, nsTemplateTier *toolchainv1alpha1.NSTemplateTier) NSTemplateTierDef { - return func() (string, *toolchainv1alpha1.NSTemplateTier) { - return identifier, nsTemplateTier - } -} - -func NewNSTemplateTierService(nsTemplateTierDefs ...NSTemplateTierDef) *NSTemplateTierService { - sc := newFakeNSTemplateTierService() - for _, nsTemplateTierDef := range nsTemplateTierDefs { - identifier, nstemplatetier := nsTemplateTierDef() - sc.addNSTemplateTier(identifier, nstemplatetier) - } - return sc -} - -func newFakeNSTemplateTierService() *NSTemplateTierService { - f := &NSTemplateTierService{} - f.MockGetNsTemplateTier = f.DefaultMockGetNSTemplateTier() - return f -} - -func (n *NSTemplateTierService) addNSTemplateTier(identifier string, nsTemplateTier *toolchainv1alpha1.NSTemplateTier) *NSTemplateTierService { - if n.tiers == nil { - n.tiers = make(map[string]*toolchainv1alpha1.NSTemplateTier) - } - n.tiers[identifier] = nsTemplateTier - return n -} - -type NSTemplateTierService struct { - MockGetNsTemplateTier func(tierName string) (*toolchainv1alpha1.NSTemplateTier, error) - tiers map[string]*toolchainv1alpha1.NSTemplateTier -} - -func (n *NSTemplateTierService) DefaultMockGetNSTemplateTier() func(tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { - return func(tierName string) (nsTemplateTier *toolchainv1alpha1.NSTemplateTier, e error) { - tier := n.tiers[tierName] - if tier != nil { - return tier, nil - } - return nil, nil - } -} - -func (n *NSTemplateTierService) GetNSTemplateTierFromInformer(_ *gin.Context, tierName string) (*toolchainv1alpha1.NSTemplateTier, error) { - return n.MockGetNsTemplateTier(tierName) -} - type SignupDef func() (string, *signup.Signup) func Signup(identifier string, userSignup *signup.Signup) SignupDef { From db915bfe4314a52781658df4df29ec6bc34f36e6 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 27 Sep 2023 11:46:22 +0200 Subject: [PATCH 11/26] Update pkg/proxy/handlers/spacelister.go Co-authored-by: Matous Jobanek --- pkg/proxy/handlers/spacelister.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index d576443d..c4ce0b7f 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -233,11 +233,9 @@ func (s *SpaceLister) getSpace(spaceBinding *toolchainv1alpha1.SpaceBinding) (*t } func getRolesFromNSTemplateTier(nstemplatetier *toolchainv1alpha1.NSTemplateTier) []string { - roles := make([]string, len(nstemplatetier.Spec.SpaceRoles)) - i := 0 + roles := make([]string, 0, len(nstemplatetier.Spec.SpaceRoles)) for k := range nstemplatetier.Spec.SpaceRoles { - roles[i] = k - i++ + roles = append(roles, k) } sort.Strings(roles) return roles From 01759250a7329b5df84baeca99ea984bd28029ec Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 27 Sep 2023 11:46:00 +0200 Subject: [PATCH 12/26] move usersignup retrieval , retrun error in case of more the one spacebining for get, add more tests --- pkg/proxy/handlers/spacelister.go | 67 +++++++++++--------------- pkg/proxy/handlers/spacelister_test.go | 39 +++++++++++++++ 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index c4ce0b7f..625cdacd 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -37,20 +37,6 @@ func NewSpaceLister(app application.Application) *SpaceLister { } func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { - userID, _ := ctx.Get(context.SubKey).(string) - username, _ := ctx.Get(context.UsernameKey).(string) - - userSignup, err := s.GetSignupFunc(nil, userID, username, false) - if err != nil { - ctx.Logger().Error(errs.Wrap(err, "error retrieving userSignup")) - return errorResponse(ctx, apierrors.NewInternalError(err)) - } - if userSignup == nil || userSignup.CompliantUsername == "" { - // account exists but the compliant username is not set yet, meaning it has not been fully provisioned yet - // return empty workspace list - return listWorkspaceResponse(ctx, []toolchainv1alpha1.Workspace{}) - } - // list all user workspaces workspaces, err := s.ListUserWorkspaces(ctx) if err != nil { @@ -60,38 +46,36 @@ func (s *SpaceLister) HandleSpaceListRequest(ctx echo.Context) error { } func (s *SpaceLister) HandleSpaceGetRequest(ctx echo.Context) error { - userID, _ := ctx.Get(context.SubKey).(string) - username, _ := ctx.Get(context.UsernameKey).(string) - workspaceName := ctx.Param("workspace") - - userSignup, err := s.GetSignupFunc(nil, userID, username, false) - if err != nil { - ctx.Logger().Error(errs.Wrap(err, "error retrieving userSignup")) - return errorResponse(ctx, apierrors.NewInternalError(err)) - } - if userSignup == nil || userSignup.CompliantUsername == "" { - // account exists but the compliant username is not set yet, meaning it has not been fully provisioned yet - // return not found response when specific workspace request was issued - r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} - return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) - - } - // get specific workspace - workspace, err := s.GetUserWorkspace(ctx, userSignup) + workspace, err := s.GetUserWorkspace(ctx) if err != nil { return errorResponse(ctx, apierrors.NewInternalError(err)) } if workspace == nil { // not found r := schema.GroupResource{Group: "toolchain.dev.openshift.com", Resource: "workspaces"} - return errorResponse(ctx, apierrors.NewNotFound(r, workspaceName)) + return errorResponse(ctx, apierrors.NewNotFound(r, ctx.Param("workspace"))) } return getWorkspaceResponse(ctx, workspace) } -func (s *SpaceLister) GetUserWorkspace(ctx echo.Context, signup *signup.Signup) (*toolchainv1alpha1.Workspace, error) { - murName := signup.CompliantUsername +func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Workspace, error) { + userID, _ := ctx.Get(context.SubKey).(string) + username, _ := ctx.Get(context.UsernameKey).(string) + + userSignup, err := s.GetSignupFunc(nil, userID, username, false) + if err != nil { + cause := errs.Wrap(err, "error retrieving userSignup") + ctx.Logger().Error(cause) + return nil, cause + } + if userSignup == nil || userSignup.CompliantUsername == "" { + // account exists but the compliant username is not set yet, meaning it has not been fully provisioned yet + // return not found response when specific workspace request was issued + return nil, nil + + } + murName := userSignup.CompliantUsername spaceBinding, err := s.listSpaceBindingForUserAndSpace(ctx, murName) if err != nil { ctx.Logger().Error(errs.Wrap(err, "error listing space bindings")) @@ -122,7 +106,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context, signup *signup.Signup) } getOnlyWSOptions := commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)) - return createWorkspaceObject(signup.Name, space, spaceBinding, getOnlyWSOptions), nil + return createWorkspaceObject(userSignup.Name, space, spaceBinding, getOnlyWSOptions), nil } func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1.Workspace, error) { @@ -176,10 +160,15 @@ func (s *SpaceLister) listSpaceBindingForUserAndSpace(ctx echo.Context, murName return nil, err } - // let's only log the issue and consider this as not found - if len(spaceBindings) != 1 { - ctx.Logger().Error("expected only 1 spacebinding, got %d for user %s and workspace %s", len(spaceBindings), murName, workspaceName) + if len(spaceBindings) == 0 { + // let's only log the issue and consider this as not found + ctx.Logger().Error(fmt.Sprintf("expected only 1 spacebinding, got 0 for user %s and workspace %s", murName, workspaceName)) return nil, nil + } else if len(spaceBindings) > 1 { + // internal server error + cause := fmt.Errorf("expected only 1 spacebinding, got %d for user %s and workspace %s", len(spaceBindings), murName, workspaceName) + ctx.Logger().Error(cause.Error()) + return nil, cause } return &spaceBindings[0], nil diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index 6168b1ac..165b2f71 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -184,6 +184,7 @@ func TestSpaceLister(t *testing.T) { expectedErr string expectedErrCode int expectedWorkspace string + overrideSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) overrideInformerFunc func() service.InformerService }{ "dancelover gets dancelover space": { @@ -252,12 +253,50 @@ func TestSpaceLister(t *testing.T) { }, expectedWorkspace: "dancelover", }, + "too many spacebindings for user": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "Internal error occurred: expected only 1 spacebinding, got 2 for user dancelover and workspace dancelover", + expectedErrCode: 500, + overrideInformerFunc: func() service.InformerService { + inf := fake.NewFakeInformer() + inf.ListSpaceBindingFunc = func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { + // let's return more than 1 spacebinding to trigger the error + return []toolchainv1alpha1.SpaceBinding{ + *fake.NewSpaceBinding("dancer-sb1", "dancelover", "dancelover", "admin"), + *fake.NewSpaceBinding("dancer-sb2", "dancelover", "dancelover", "other"), + }, nil + } + return inf + }, + expectedWorkspace: "dancelover", + }, + "get signup error": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "signup error", + expectedErrCode: 500, + overrideSignupFunc: func(ctx *gin.Context, userID, username string, checkUserSignupComplete bool) (*signup.Signup, error) { + return nil, fmt.Errorf("signup error") + }, + expectedWorkspace: "dancelover", + }, + "signup has no compliant username set": { + username: "racing.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "\"workspaces.toolchain.dev.openshift.com \\\"racinglover\\\" not found\"", + expectedErrCode: 404, + expectedWorkspace: "racinglover", + }, } for k, tc := range tests { t.Run(k, func(t *testing.T) { // given signupProvider := fakeSignupService.GetSignupFromInformer + if tc.overrideSignupFunc != nil { + signupProvider = tc.overrideSignupFunc + } informerFunc := getFakeInformerService(fakeClient) if tc.overrideInformerFunc != nil { From a1507b363c60f83d302ce5aa6c429861836582f4 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Fri, 29 Sep 2023 10:37:18 +0200 Subject: [PATCH 13/26] populate binding list in workspace type --- go.mod | 2 +- go.sum | 16 ++- pkg/proxy/handlers/spacelister.go | 133 +++++++++++++++--------- pkg/proxy/handlers/spacelister_test.go | 135 +++++++++++++++++++++++-- test/fake/informer.go | 38 ++++--- 5 files changed, 247 insertions(+), 77 deletions(-) diff --git a/go.mod b/go.mod index 8b39609f..b744e799 100644 --- a/go.mod +++ b/go.mod @@ -137,4 +137,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20230920171626-876ba9b0d3c4 +replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20230929083126-a3a39b0b6fee diff --git a/go.sum b/go.sum index 431e894e..710a47ae 100644 --- a/go.sum +++ b/go.sum @@ -61,7 +61,11 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= @@ -290,6 +294,7 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslC github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= @@ -363,10 +368,12 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/mfrancisc/toolchain-common v0.0.0-20230920171626-876ba9b0d3c4 h1:XIw5csoJ0Ydw0Aoeg9heZv031pujrDgeSv9S5h3OUEE= -github.com/mfrancisc/toolchain-common v0.0.0-20230920171626-876ba9b0d3c4/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= +github.com/mfrancisc/toolchain-common v0.0.0-20230929083126-a3a39b0b6fee h1:N8zcrP3xcnnlBKFqxK8AD2Bj+YGW9/qDy+gxpQGYUGM= +github.com/mfrancisc/toolchain-common v0.0.0-20230929083126-a3a39b0b6fee/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -401,13 +408,16 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/redhat-cop/operator-utils v1.3.3-0.20220121120056-862ef22b8cdf h1:fsZiv9XuFo8G7IyzFWjG02vqzJG7kSqFvD1Wiq3V/o8= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -965,6 +975,7 @@ k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= +k8s.io/component-base v0.25.0 h1:haVKlLkPCFZhkcqB6WCvpVxftrg6+FK5x1ZuaIDaQ5Y= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= @@ -972,6 +983,7 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/kubectl v0.24.0 h1:nA+WtMLVdXUs4wLogGd1mPTAesnLdBpCVgCmz3I7dXo= k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 625cdacd..26615874 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -13,8 +13,8 @@ import ( "github.com/codeready-toolchain/registration-service/pkg/log" "github.com/codeready-toolchain/registration-service/pkg/signup" commonproxy "github.com/codeready-toolchain/toolchain-common/pkg/proxy" + "github.com/codeready-toolchain/toolchain-common/pkg/spacebinding" "github.com/gin-gonic/gin" - "github.com/labstack/echo/v4" errs "github.com/pkg/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -24,6 +24,15 @@ import ( "k8s.io/apimachinery/pkg/selection" ) +const ( + // UpdateBindingAction specifies that the current binding can be updated by providing a different Space Role. + UpdateBindingAction = "update" + // DeleteBindingAction specifies that the current binding can be deleted in order to revoke user access to the Space. + DeleteBindingAction = "delete" + // OverrideBindingAction specifies that the current binding can be overridden by creating a SpaceBinding containing the same MUR but different Space Role. + OverrideBindingAction = "override" +) + type SpaceLister struct { GetSignupFunc func(ctx *gin.Context, userID, username string, checkUserSignupCompleted bool) (*signup.Signup, error) GetInformerServiceFunc func() service.InformerService @@ -62,6 +71,7 @@ func (s *SpaceLister) HandleSpaceGetRequest(ctx echo.Context) error { func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Workspace, error) { userID, _ := ctx.Get(context.SubKey).(string) username, _ := ctx.Get(context.UsernameKey).(string) + workspaceName := ctx.Param("workspace") userSignup, err := s.GetSignupFunc(nil, userID, username, false) if err != nil { @@ -75,28 +85,45 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor return nil, nil } - murName := userSignup.CompliantUsername - spaceBinding, err := s.listSpaceBindingForUserAndSpace(ctx, murName) + space, err := s.GetInformerServiceFunc().GetSpace(workspaceName) if err != nil { - ctx.Logger().Error(errs.Wrap(err, "error listing space bindings")) - return nil, err - } - if spaceBinding == nil { - // spacebinding not found, let's return a nil workspace which causes the handler to respond with a 404 status code + ctx.Logger().Error(errs.Wrap(err, "unable to get space")) return nil, nil } - space, err := s.getSpace(spaceBinding) + // recursively get all the spacebindings for the current workspace + listSpaceBindingsFunc := func(spaceName string) ([]toolchainv1alpha1.SpaceBinding, error) { + spaceSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingSpaceLabelKey, selection.Equals, []string{spaceName}) + if err != nil { + return nil, err + } + return s.GetInformerServiceFunc().ListSpaceBindings(*spaceSelector) + } + getSpaceFunc := func(spaceName string) (*toolchainv1alpha1.Space, error) { + return s.GetInformerServiceFunc().GetSpace(spaceName) + } + spaceBindingLister := spacebinding.NewLister(listSpaceBindingsFunc, getSpaceFunc) + allSpaceBindings, err := spaceBindingLister.RecursiveListForSpace(space, []toolchainv1alpha1.SpaceBinding{}) if err != nil { - ctx.Logger().Error(errs.Wrap(err, "unable to get space")) + ctx.Logger().Error(err, "failed to list space bindings") return nil, err } - // ------------- - // TODO recursively get all the spacebindings for the current workspace - // and build the Bindings list with the available actions + // check if user has access to this workspace + userBindings := filterUserSpaceBindings(userSignup.CompliantUsername, allSpaceBindings) + if len(userBindings) == 0 { + // let's only log the issue and consider this as not found + ctx.Logger().Error(fmt.Sprintf("expected only 1 spacebinding, got 0 for user %s and workspace %s", userSignup.CompliantUsername, workspaceName)) + return nil, nil + } else if len(userBindings) > 1 { + // internal server error + cause := fmt.Errorf("expected only 1 spacebinding, got %d for user %s and workspace %s", len(userBindings), userSignup.CompliantUsername, workspaceName) + ctx.Logger().Error(cause.Error()) + return nil, cause + } + // build the Bindings list with the available actions // this field is populated only for the GET workspace request - // ------------- + bindings := generateWorkspaceBindings(space, allSpaceBindings) // add available roles, this field is populated only for the GET workspace request nsTemplateTier, err := s.GetInformerServiceFunc().GetNSTemplateTier(space.Spec.TierName) @@ -104,9 +131,11 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor ctx.Logger().Error(errs.Wrap(err, "unable to get nstemplatetier")) return nil, err } - getOnlyWSOptions := commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)) - return createWorkspaceObject(userSignup.Name, space, spaceBinding, getOnlyWSOptions), nil + return createWorkspaceObject(userSignup.Name, space, &userBindings[0], + commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)), + commonproxy.WithBindings(bindings), + ), nil } func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1.Workspace, error) { @@ -142,38 +171,6 @@ func (s *SpaceLister) listSpaceBindingsForUser(murName string) ([]toolchainv1alp return s.GetInformerServiceFunc().ListSpaceBindings(requirements...) } -func (s *SpaceLister) listSpaceBindingForUserAndSpace(ctx echo.Context, murName string) (*toolchainv1alpha1.SpaceBinding, error) { - workspaceName := ctx.Param("workspace") - murSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingMasterUserRecordLabelKey, selection.Equals, []string{murName}) - if err != nil { - return nil, err - } - // specific workspace requested so add label requirement to match the space - spaceSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingSpaceLabelKey, selection.Equals, []string{workspaceName}) - if err != nil { - return nil, err - } - requirements := []labels.Requirement{*murSelector, *spaceSelector} - - spaceBindings, err := s.GetInformerServiceFunc().ListSpaceBindings(requirements...) - if err != nil { - return nil, err - } - - if len(spaceBindings) == 0 { - // let's only log the issue and consider this as not found - ctx.Logger().Error(fmt.Sprintf("expected only 1 spacebinding, got 0 for user %s and workspace %s", murName, workspaceName)) - return nil, nil - } else if len(spaceBindings) > 1 { - // internal server error - cause := fmt.Errorf("expected only 1 spacebinding, got %d for user %s and workspace %s", len(spaceBindings), murName, workspaceName) - ctx.Logger().Error(cause.Error()) - return nil, cause - } - - return &spaceBindings[0], nil -} - func (s *SpaceLister) workspacesFromSpaceBindings(signupName string, spaceBindings []toolchainv1alpha1.SpaceBinding) []toolchainv1alpha1.Workspace { workspaces := []toolchainv1alpha1.Workspace{} for i := range spaceBindings { @@ -256,3 +253,43 @@ func errorResponse(ctx echo.Context, err *apierrors.StatusError) error { ctx.Response().Writer.WriteHeader(int(err.ErrStatus.Code)) return json.NewEncoder(ctx.Response().Writer).Encode(err.ErrStatus) } + +// filterUserSpaceBindings returns all the spacebindings for a given username +func filterUserSpaceBindings(username string, allSpaceBindings []toolchainv1alpha1.SpaceBinding) (outputBindings []toolchainv1alpha1.SpaceBinding) { + for _, binding := range allSpaceBindings { + if binding.Spec.MasterUserRecord == username { + outputBindings = append(outputBindings, binding) + } + } + return outputBindings +} + +// generateWorkspaceBindings generates the bindings list starting from the spacebindings found on a given space resource and an all parent spaces. +// The Bindings list has the available actions for each entry in the list. +func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []toolchainv1alpha1.SpaceBinding) []toolchainv1alpha1.Binding { + var bindings []toolchainv1alpha1.Binding + for _, spaceBinding := range spaceBindings { + binding := toolchainv1alpha1.Binding{ + MasterUserRecord: spaceBinding.Spec.MasterUserRecord, + Role: spaceBinding.Spec.SpaceRole, + AvailableActions: []string{}, + } + if name, exists := spaceBinding.GetLabels()[toolchainv1alpha1.SpaceBindingSpaceLabelKey]; exists && name == space.GetName() { + // this is a binding that was created on the current space, it can be updated or deleted + binding.AvailableActions = []string{UpdateBindingAction, DeleteBindingAction} + } else { + // this is a binding that was inherited from a parent space, + // it can only be overridden by another spacebinding containing the same MUR but different role. + binding.AvailableActions = []string{OverrideBindingAction} + } + bindings = append(bindings, binding) + } + + // let's sort the list based on username, + // in order to make it deterministic + sort.Slice(bindings, func(i, j int) bool { + return bindings[i].MasterUserRecord < bindings[j].MasterUserRecord + }) + + return bindings +} diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index 165b2f71..44c06656 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -14,6 +14,7 @@ import ( "github.com/codeready-toolchain/registration-service/pkg/proxy/handlers" "github.com/codeready-toolchain/registration-service/pkg/signup" "github.com/codeready-toolchain/registration-service/test/fake" + spacetest "github.com/codeready-toolchain/toolchain-common/pkg/test/space" "github.com/gin-gonic/gin" "sigs.k8s.io/controller-runtime/pkg/client" @@ -37,6 +38,7 @@ func TestSpaceLister(t *testing.T) { newSignup("movielover", "movie.lover", true), newSignup("pandalover", "panda.lover", true), newSignup("usernospace", "user.nospace", true), + newSignup("foodlover", "food.lover", true), newSignup("racinglover", "racing.lover", false), ) @@ -49,6 +51,7 @@ func TestSpaceLister(t *testing.T) { fake.NewSpace("dancelover", "member-1", "dancelover"), fake.NewSpace("movielover", "member-1", "movielover"), fake.NewSpace("racinglover", "member-2", "racinglover"), + fake.NewSpace("foodlover", "member-2", "foodlover", spacetest.WithSpecParentSpace("dancelover")), spaceNotProvisionedYet, //spacebindings @@ -195,6 +198,13 @@ func TestSpaceLister(t *testing.T) { "admin", "viewer", }, ), + commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "dancelover", + Role: "admin", + AvailableActions: []string{"update", "delete"}, + }, + }), ), }, expectedErr: "", @@ -206,18 +216,63 @@ func TestSpaceLister(t *testing.T) { workspaceFor(t, fakeClient, "movielover", "other", false, commonproxy.WithAvailableRoles([]string{ "admin", "viewer", - })), + }), + commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "dancelover", + Role: "other", + AvailableActions: []string{"update", "delete"}, + }, + { + MasterUserRecord: "movielover", + Role: "admin", + AvailableActions: []string{"update", "delete"}, + }, + }), + ), }, expectedErr: "", expectedWorkspace: "movielover", }, + "dancelover gets foodlover space": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{ + workspaceFor(t, fakeClient, "foodlover", "admin", false, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + }), + commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "dancelover", + Role: "admin", // dancelover is admin since it's admin on the parent space, + AvailableActions: []string{"override"}, // since the binding is inherited from parent space, then it can only be overridden + }, + }), + ), + }, + expectedErr: "", + expectedWorkspace: "foodlover", + }, "movielover gets movielover space": { username: "movie.lover", expectedWs: []toolchainv1alpha1.Workspace{ workspaceFor(t, fakeClient, "movielover", "admin", true, commonproxy.WithAvailableRoles([]string{ "admin", "viewer", - })), + }), + commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "dancelover", + Role: "other", + AvailableActions: []string{"update", "delete"}, + }, + { + MasterUserRecord: "movielover", + Role: "admin", + AvailableActions: []string{"update", "delete"}, + }, + }), + ), }, expectedErr: "", expectedWorkspace: "movielover", @@ -235,7 +290,20 @@ func TestSpaceLister(t *testing.T) { workspaceFor(t, fakeClient, "movielover", "admin", true, commonproxy.WithAvailableRoles([]string{ "admin", "viewer", - })), + }), + commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "dancelover", + Role: "other", + AvailableActions: []string{"update", "delete"}, + }, + { + MasterUserRecord: "movielover", + Role: "admin", + AvailableActions: []string{"update", "delete"}, + }, + }), + ), }, expectedErr: "", expectedWorkspace: "movielover", @@ -259,15 +327,14 @@ func TestSpaceLister(t *testing.T) { expectedErr: "Internal error occurred: expected only 1 spacebinding, got 2 for user dancelover and workspace dancelover", expectedErrCode: 500, overrideInformerFunc: func() service.InformerService { - inf := fake.NewFakeInformer() - inf.ListSpaceBindingFunc = func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { + listSpaceBindingFunc := func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { // let's return more than 1 spacebinding to trigger the error return []toolchainv1alpha1.SpaceBinding{ *fake.NewSpaceBinding("dancer-sb1", "dancelover", "dancelover", "admin"), *fake.NewSpaceBinding("dancer-sb2", "dancelover", "dancelover", "other"), }, nil } - return inf + return getFakeInformerService(fakeClient, WithListSpaceBindingFunc(listSpaceBindingFunc))() }, expectedWorkspace: "dancelover", }, @@ -288,6 +355,50 @@ func TestSpaceLister(t *testing.T) { expectedErrCode: 404, expectedWorkspace: "racinglover", }, + "list spacebindings error": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "list spacebindings error", + expectedErrCode: 500, + overrideInformerFunc: func() service.InformerService { + listSpaceBindingFunc := func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { + return nil, fmt.Errorf("list spacebindings error") + } + return getFakeInformerService(fakeClient, WithListSpaceBindingFunc(listSpaceBindingFunc))() + }, + expectedWorkspace: "dancelover", + }, + "unable to get space": { + username: "dance.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "\"workspaces.toolchain.dev.openshift.com \\\"dancelover\\\" not found\"", + expectedErrCode: 404, + overrideInformerFunc: func() service.InformerService { + getSpaceFunc := func(name string) (*toolchainv1alpha1.Space, error) { + return nil, fmt.Errorf("no space") + } + return getFakeInformerService(fakeClient, WithGetSpaceFunc(getSpaceFunc))() + }, + expectedWorkspace: "dancelover", + }, + "unable to get parent-space": { + username: "food.lover", + expectedWs: []toolchainv1alpha1.Workspace{}, + expectedErr: "Internal error occurred: unable to get parent-space: parent-space error", + expectedErrCode: 500, + overrideInformerFunc: func() service.InformerService { + getSpaceFunc := func(name string) (*toolchainv1alpha1.Space, error) { + if name == "dancelover" { + // return the error only when trying to get the parent space + return nil, fmt.Errorf("parent-space error") + } + // return the foodlover space + return fake.NewSpace("foodlover", "member-2", "foodlover", spacetest.WithSpecParentSpace("dancelover")), nil + } + return getFakeInformerService(fakeClient, WithGetSpaceFunc(getSpaceFunc))() + }, + expectedWorkspace: "foodlover", + }, } for k, tc := range tests { @@ -366,6 +477,18 @@ func WithGetNSTemplateTierFunc(getNsTemplateTierFunc func(tier string) (*toolcha } } +func WithListSpaceBindingFunc(listSpaceBindingFunc func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error)) InformerServiceOptions { + return func(informer *fake.Informer) { + informer.ListSpaceBindingFunc = listSpaceBindingFunc + } +} + +func WithGetSpaceFunc(getSpaceFunc func(name string) (*toolchainv1alpha1.Space, error)) InformerServiceOptions { + return func(informer *fake.Informer) { + informer.GetSpaceFunc = getSpaceFunc + } +} + func getFakeInformerService(fakeClient client.Client, options ...InformerServiceOptions) func() service.InformerService { return func() service.InformerService { diff --git a/test/fake/informer.go b/test/fake/informer.go index 9f8bd55c..f97efa14 100644 --- a/test/fake/informer.go +++ b/test/fake/informer.go @@ -3,6 +3,7 @@ package fake import ( toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" "github.com/codeready-toolchain/registration-service/pkg/configuration" + spacetest "github.com/codeready-toolchain/toolchain-common/pkg/test/space" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -71,22 +72,15 @@ func (f Informer) GetNSTemplateTier(tier string) (*toolchainv1alpha1.NSTemplateT panic("not supposed to call GetNSTemplateTierFunc") } -func NewSpace(name, targetCluster, compliantUserName string) *toolchainv1alpha1.Space { - space := &toolchainv1alpha1.Space{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: configuration.Namespace(), - Labels: map[string]string{ - toolchainv1alpha1.SpaceCreatorLabelKey: compliantUserName, - }, - }, - Spec: toolchainv1alpha1.SpaceSpec{ - TargetCluster: targetCluster, - TierName: "base1ns", - }, - Status: toolchainv1alpha1.SpaceStatus{ - TargetCluster: targetCluster, - ProvisionedNamespaces: []toolchainv1alpha1.SpaceNamespace{ +func NewSpace(name, targetCluster, compliantUserName string, spaceTestOptions ...spacetest.Option) *toolchainv1alpha1.Space { + + spaceTestOptions = append(spaceTestOptions, + spacetest.WithLabel(toolchainv1alpha1.SpaceCreatorLabelKey, compliantUserName), + spacetest.WithSpecTargetCluster(targetCluster), + spacetest.WithStatusTargetCluster(targetCluster), + spacetest.WithTierName("base1ns"), + spacetest.WithStatusProvisionedNamespaces( + []toolchainv1alpha1.SpaceNamespace{ { Name: "john-dev", Type: "default", @@ -95,9 +89,11 @@ func NewSpace(name, targetCluster, compliantUserName string) *toolchainv1alpha1. Name: "john-stage", }, }, - }, - } - return space + ), + ) + return spacetest.NewSpace(configuration.Namespace(), name, + spaceTestOptions..., + ) } func NewSpaceBinding(name, murLabelValue, spaceLabelValue, role string) *toolchainv1alpha1.SpaceBinding { @@ -110,7 +106,9 @@ func NewSpaceBinding(name, murLabelValue, spaceLabelValue, role string) *toolcha }, }, Spec: toolchainv1alpha1.SpaceBindingSpec{ - SpaceRole: role, + SpaceRole: role, + MasterUserRecord: murLabelValue, + Space: spaceLabelValue, }, } } From 4704269e33b78588b5065f2c3184be8c78b1e857 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Fri, 29 Sep 2023 11:03:42 +0200 Subject: [PATCH 14/26] fix spacelist unit test --- pkg/proxy/handlers/spacelister_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index c211abc4..40ef195e 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -315,6 +315,7 @@ func TestSpaceLister(t *testing.T) { rec := httptest.NewRecorder() ctx := e.NewContext(req, rec) ctx.Set(rcontext.UsernameKey, tc.username) + ctx.Set(rcontext.RequestReceivedTime, time.Now()) ctx.SetParamNames("workspace") ctx.SetParamValues(tc.expectedWorkspace) From 7130609e5366799fcd08a137b60fa90eb4422935 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 2 Oct 2023 17:32:24 +0200 Subject: [PATCH 15/26] update common --- go.mod | 2 +- go.sum | 4 ++-- pkg/proxy/handlers/spacelister.go | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index a4bd14a9..ce1a4a69 100644 --- a/go.mod +++ b/go.mod @@ -145,4 +145,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20230929083126-a3a39b0b6fee +replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e diff --git a/go.sum b/go.sum index d6bdbbab..42f819ec 100644 --- a/go.sum +++ b/go.sum @@ -371,8 +371,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mfrancisc/toolchain-common v0.0.0-20230929083126-a3a39b0b6fee h1:N8zcrP3xcnnlBKFqxK8AD2Bj+YGW9/qDy+gxpQGYUGM= -github.com/mfrancisc/toolchain-common v0.0.0-20230929083126-a3a39b0b6fee/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= +github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e h1:P4C77qKcRLx9BJ8vnYaX6MC84SUCrz6EldhhiIazHHA= +github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 97e636bc..54ef6f81 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -6,6 +6,8 @@ import ( "net/http" "sort" + "time" + toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" "github.com/codeready-toolchain/registration-service/pkg/application" "github.com/codeready-toolchain/registration-service/pkg/application/service" @@ -16,7 +18,6 @@ import ( commonproxy "github.com/codeready-toolchain/toolchain-common/pkg/proxy" "github.com/codeready-toolchain/toolchain-common/pkg/spacebinding" "github.com/gin-gonic/gin" - "time" "github.com/labstack/echo/v4" errs "github.com/pkg/errors" @@ -113,7 +114,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor return s.GetInformerServiceFunc().GetSpace(spaceName) } spaceBindingLister := spacebinding.NewLister(listSpaceBindingsFunc, getSpaceFunc) - allSpaceBindings, err := spaceBindingLister.RecursiveListForSpace(space, []toolchainv1alpha1.SpaceBinding{}) + allSpaceBindings, err := spaceBindingLister.ListForSpace(space, []toolchainv1alpha1.SpaceBinding{}) if err != nil { ctx.Logger().Error(err, "failed to list space bindings") return nil, err From 9160b2e6a493e795032c225d1ec8ebb8c3763b30 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 9 Oct 2023 12:40:33 +0200 Subject: [PATCH 16/26] Update pkg/proxy/handlers/spacelister.go Co-authored-by: Matous Jobanek --- pkg/proxy/handlers/spacelister.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 54ef6f81..9d37fbec 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -33,7 +33,7 @@ const ( UpdateBindingAction = "update" // DeleteBindingAction specifies that the current binding can be deleted in order to revoke user access to the Space. DeleteBindingAction = "delete" - // OverrideBindingAction specifies that the current binding can be overridden by creating a SpaceBinding containing the same MUR but different Space Role. + // OverrideBindingAction specifies that the current binding can be overridden by creating a SpaceBindingRequest containing the same MUR but different Space Role. OverrideBindingAction = "override" ) From 418ef6a2c5fa9c230997861cf55c8b7ef24f837a Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 9 Oct 2023 12:57:59 +0200 Subject: [PATCH 17/26] wip add sbr to bindings request --- pkg/proxy/handlers/spacelister.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 9d37fbec..da7b2fb1 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -134,7 +134,11 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor } // build the Bindings list with the available actions // this field is populated only for the GET workspace request - bindings := generateWorkspaceBindings(space, allSpaceBindings) + bindings, err := generateWorkspaceBindings(space, allSpaceBindings) + if err != nil { + ctx.Logger().Error(errs.Wrap(err, "unable to generate bindings field")) + return nil, err + } // add available roles, this field is populated only for the GET workspace request nsTemplateTier, err := s.GetInformerServiceFunc().GetNSTemplateTier(space.Spec.TierName) @@ -277,7 +281,7 @@ func filterUserSpaceBindings(username string, allSpaceBindings []toolchainv1alph // generateWorkspaceBindings generates the bindings list starting from the spacebindings found on a given space resource and an all parent spaces. // The Bindings list has the available actions for each entry in the list. -func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []toolchainv1alpha1.SpaceBinding) []toolchainv1alpha1.Binding { +func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []toolchainv1alpha1.SpaceBinding) ([]toolchainv1alpha1.Binding, error) { var bindings []toolchainv1alpha1.Binding for _, spaceBinding := range spaceBindings { binding := toolchainv1alpha1.Binding{ @@ -285,8 +289,12 @@ func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []t Role: spaceBinding.Spec.SpaceRole, AvailableActions: []string{}, } - if name, exists := spaceBinding.GetLabels()[toolchainv1alpha1.SpaceBindingSpaceLabelKey]; exists && name == space.GetName() { - // this is a binding that was created on the current space, it can be updated or deleted + if SBRName, isSBRBinding := spaceBinding.GetLabels()[toolchainv1alpha1.SpaceBindingRequestLabelKey]; isSBRBinding { + if SBRName == "" { + // small corner case where the SBR name for some reason is not generated + return nil, fmt.Errorf("SpaceBindingRequest name not found on binding: %s", spaceBinding.GetName()) + } + // this is a binding that was created via SpaceBindingRequest, it can be updated or deleted binding.AvailableActions = []string{UpdateBindingAction, DeleteBindingAction} } else { // this is a binding that was inherited from a parent space, @@ -302,5 +310,5 @@ func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []t return bindings[i].MasterUserRecord < bindings[j].MasterUserRecord }) - return bindings + return bindings, nil } From 64ba7bab696d459bc4b170749685a926b15b6f0e Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 9 Oct 2023 14:50:59 +0200 Subject: [PATCH 18/26] check for SBR label and populate bindingRequest field --- go.mod | 2 + go.sum | 4 +- pkg/proxy/handlers/spacelister.go | 22 +++++-- pkg/proxy/handlers/spacelister_test.go | 86 ++++++++++++++++++++++++-- 4 files changed, 102 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index ce1a4a69..715caa4f 100644 --- a/go.mod +++ b/go.mod @@ -146,3 +146,5 @@ require ( ) replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e + +replace github.com/codeready-toolchain/api => github.com/mfrancisc/api v0.0.0-20231009110929-3412d406675e diff --git a/go.sum b/go.sum index 42f819ec..87922f6c 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,6 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33 h1:hxXfcFq2JgFISVxrkISg8m9DZMzpcPWRjPspx3M3Sxo= -github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -371,6 +369,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mfrancisc/api v0.0.0-20231009110929-3412d406675e h1:X7Cous9+l2Ju7t8IPEtebiOuF8OsZRmUIZlt4tvFFvc= +github.com/mfrancisc/api v0.0.0-20231009110929-3412d406675e/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e h1:P4C77qKcRLx9BJ8vnYaX6MC84SUCrz6EldhhiIazHHA= github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index da7b2fb1..72ebc69c 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -134,7 +134,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor } // build the Bindings list with the available actions // this field is populated only for the GET workspace request - bindings, err := generateWorkspaceBindings(space, allSpaceBindings) + bindings, err := generateWorkspaceBindings(allSpaceBindings) if err != nil { ctx.Logger().Error(errs.Wrap(err, "unable to generate bindings field")) return nil, err @@ -281,7 +281,7 @@ func filterUserSpaceBindings(username string, allSpaceBindings []toolchainv1alph // generateWorkspaceBindings generates the bindings list starting from the spacebindings found on a given space resource and an all parent spaces. // The Bindings list has the available actions for each entry in the list. -func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []toolchainv1alpha1.SpaceBinding) ([]toolchainv1alpha1.Binding, error) { +func generateWorkspaceBindings(spaceBindings []toolchainv1alpha1.SpaceBinding) ([]toolchainv1alpha1.Binding, error) { var bindings []toolchainv1alpha1.Binding for _, spaceBinding := range spaceBindings { binding := toolchainv1alpha1.Binding{ @@ -289,16 +289,26 @@ func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []t Role: spaceBinding.Spec.SpaceRole, AvailableActions: []string{}, } - if SBRName, isSBRBinding := spaceBinding.GetLabels()[toolchainv1alpha1.SpaceBindingRequestLabelKey]; isSBRBinding { - if SBRName == "" { - // small corner case where the SBR name for some reason is not generated + sbrName, sbrNameFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] + sbrNamespace, sbrNamespaceFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] + if sbrNameFound || sbrNamespaceFound { + if sbrName == "" { + // small corner case where the SBR name for some reason is not present as labels on the sb. return nil, fmt.Errorf("SpaceBindingRequest name not found on binding: %s", spaceBinding.GetName()) } + if sbrNamespace == "" { + // small corner case where the SBR namespace for some reason is not present as labels on the sb. + return nil, fmt.Errorf("SpaceBindingRequest namespace not found on binding: %s", spaceBinding.GetName()) + } // this is a binding that was created via SpaceBindingRequest, it can be updated or deleted binding.AvailableActions = []string{UpdateBindingAction, DeleteBindingAction} + binding.BindingRequest = toolchainv1alpha1.BindingRequest{ + Name: sbrName, + Namespace: sbrNamespace, + } } else { // this is a binding that was inherited from a parent space, - // it can only be overridden by another spacebinding containing the same MUR but different role. + // it can only be overridden by another SpaceBinding containing the same MUR but different role. binding.AvailableActions = []string{OverrideBindingAction} } bindings = append(bindings, binding) diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index d18c53a3..57b150b4 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -40,6 +40,8 @@ func TestSpaceLister(t *testing.T) { newSignup("pandalover", "panda.lover", true), newSignup("usernospace", "user.nospace", true), newSignup("foodlover", "food.lover", true), + newSignup("animelover", "anime.lover", true), + newSignup("carlover", "car.lover", true), newSignup("racinglover", "racing.lover", false), ) @@ -47,12 +49,29 @@ func TestSpaceLister(t *testing.T) { spaceNotProvisionedYet := fake.NewSpace("pandalover", "member-2", "pandalover") spaceNotProvisionedYet.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] = "" + // spacebinding associated with SpaceBindingRequest + spaceBindingWithSBR := fake.NewSpaceBinding("foodlover-sb-from-sbr", "foodlover", "movielover", "maintainer") + spaceBindingWithSBR.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] = "foodlover-sbr" + spaceBindingWithSBR.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] = "movielover-tenant" + + // spacebinding with SpaceBindingRequest but name is missing + spaceBindingWithInvalidSBRName := fake.NewSpaceBinding("carlover-sb-from-sbr", "carlover", "animelover", "viewer") + spaceBindingWithInvalidSBRName.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] = "" // let's set the name to blank in order to trigger an error + spaceBindingWithInvalidSBRName.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] = "anime-tenant" + + // spacebinding with SpaceBindingRequest but namespace is missing + spaceBindingWithInvalidSBRNamespace := fake.NewSpaceBinding("animelover-sb-from-sbr", "animelover", "carlover", "viewer") + spaceBindingWithInvalidSBRNamespace.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] = "anime-sbr" + spaceBindingWithInvalidSBRNamespace.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] = "" // let's set the name to blank in order to trigger an error + fakeClient := initFakeClient(t, // spaces fake.NewSpace("dancelover", "member-1", "dancelover"), fake.NewSpace("movielover", "member-1", "movielover"), fake.NewSpace("racinglover", "member-2", "racinglover"), fake.NewSpace("foodlover", "member-2", "foodlover", spacetest.WithSpecParentSpace("dancelover")), + fake.NewSpace("animelover", "member-1", "animelover"), + fake.NewSpace("carlover", "member-1", "carlover"), spaceNotProvisionedYet, //spacebindings @@ -60,6 +79,11 @@ func TestSpaceLister(t *testing.T) { fake.NewSpaceBinding("dancer-sb2", "dancelover", "movielover", "other"), fake.NewSpaceBinding("moviegoer-sb", "movielover", "movielover", "admin"), fake.NewSpaceBinding("racer-sb", "racinglover", "racinglover", "admin"), + fake.NewSpaceBinding("anime-sb", "animelover", "animelover", "admin"), + fake.NewSpaceBinding("car-sb", "carlover", "carlover", "admin"), + spaceBindingWithSBR, + spaceBindingWithInvalidSBRName, + spaceBindingWithInvalidSBRNamespace, //nstemplatetier fake.NewBase1NSTemplateTier(), @@ -204,7 +228,7 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "dancelover", Role: "admin", - AvailableActions: []string{"update", "delete"}, + AvailableActions: []string{"override"}, }, }), ), @@ -223,12 +247,21 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "dancelover", Role: "other", + AvailableActions: []string{"override"}, + }, + { + MasterUserRecord: "foodlover", + Role: "maintainer", AvailableActions: []string{"update", "delete"}, + BindingRequest: toolchainv1alpha1.BindingRequest{ + Name: "foodlover-sbr", + Namespace: "movielover-tenant", + }, }, { MasterUserRecord: "movielover", Role: "admin", - AvailableActions: []string{"update", "delete"}, + AvailableActions: []string{"override"}, }, }), ), @@ -262,16 +295,26 @@ func TestSpaceLister(t *testing.T) { commonproxy.WithAvailableRoles([]string{ "admin", "viewer", }), + // bindings are in alphabetical order using the MUR name commonproxy.WithBindings([]toolchainv1alpha1.Binding{ { MasterUserRecord: "dancelover", Role: "other", + AvailableActions: []string{"override"}, + }, + { + MasterUserRecord: "foodlover", + Role: "maintainer", AvailableActions: []string{"update", "delete"}, + BindingRequest: toolchainv1alpha1.BindingRequest{ + Name: "foodlover-sbr", + Namespace: "movielover-tenant", + }, }, { MasterUserRecord: "movielover", Role: "admin", - AvailableActions: []string{"update", "delete"}, + AvailableActions: []string{"override"}, }, }), ), @@ -297,12 +340,21 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "dancelover", Role: "other", + AvailableActions: []string{"override"}, + }, + { + MasterUserRecord: "foodlover", + Role: "maintainer", AvailableActions: []string{"update", "delete"}, + BindingRequest: toolchainv1alpha1.BindingRequest{ + Name: "foodlover-sbr", + Namespace: "movielover-tenant", + }, }, { MasterUserRecord: "movielover", Role: "admin", - AvailableActions: []string{"update", "delete"}, + AvailableActions: []string{"override"}, }, }), ), @@ -401,6 +453,32 @@ func TestSpaceLister(t *testing.T) { }, expectedWorkspace: "foodlover", }, + "error spaceBinding request has no name": { + username: "anime.lover", + expectedWs: []toolchainv1alpha1.Workspace{ + workspaceFor(t, fakeClient, "animelover", "admin", true, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + }), + ), + }, + expectedErr: "Internal error occurred: SpaceBindingRequest name not found on binding: carlover-sb-from-sbr", + expectedErrCode: 500, + expectedWorkspace: "animelover", + }, + "error spaceBinding request has no namespace set": { + username: "car.lover", + expectedWs: []toolchainv1alpha1.Workspace{ + workspaceFor(t, fakeClient, "carlover", "admin", true, + commonproxy.WithAvailableRoles([]string{ + "admin", "viewer", + }), + ), + }, + expectedErr: "Internal error occurred: SpaceBindingRequest namespace not found on binding: animelover-sb-from-sbr", + expectedErrCode: 500, + expectedWorkspace: "carlover", + }, } for k, tc := range tests { From 31c54dd2746668c8cc1d3328295cec5e3c3bc45a Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 9 Oct 2023 14:55:06 +0200 Subject: [PATCH 19/26] small typo --- pkg/proxy/handlers/spacelister.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 72ebc69c..caa4d351 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -308,7 +308,7 @@ func generateWorkspaceBindings(spaceBindings []toolchainv1alpha1.SpaceBinding) ( } } else { // this is a binding that was inherited from a parent space, - // it can only be overridden by another SpaceBinding containing the same MUR but different role. + // it can only be overridden by another SpaceBindingRequest containing the same MUR but different role. binding.AvailableActions = []string{OverrideBindingAction} } bindings = append(bindings, binding) From 485a52eb2119a0cf3414b82dd4726f8ace6fdf1c Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Mon, 9 Oct 2023 19:24:57 +0200 Subject: [PATCH 20/26] handle sbr created on parent space case --- pkg/proxy/handlers/spacelister.go | 17 ++++++---- pkg/proxy/handlers/spacelister_test.go | 47 +++++++++++++++++++------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index caa4d351..c965128a 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -134,7 +134,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor } // build the Bindings list with the available actions // this field is populated only for the GET workspace request - bindings, err := generateWorkspaceBindings(allSpaceBindings) + bindings, err := generateWorkspaceBindings(space, allSpaceBindings) if err != nil { ctx.Logger().Error(errs.Wrap(err, "unable to generate bindings field")) return nil, err @@ -281,7 +281,7 @@ func filterUserSpaceBindings(username string, allSpaceBindings []toolchainv1alph // generateWorkspaceBindings generates the bindings list starting from the spacebindings found on a given space resource and an all parent spaces. // The Bindings list has the available actions for each entry in the list. -func generateWorkspaceBindings(spaceBindings []toolchainv1alpha1.SpaceBinding) ([]toolchainv1alpha1.Binding, error) { +func generateWorkspaceBindings(space *toolchainv1alpha1.Space, spaceBindings []toolchainv1alpha1.SpaceBinding) ([]toolchainv1alpha1.Binding, error) { var bindings []toolchainv1alpha1.Binding for _, spaceBinding := range spaceBindings { binding := toolchainv1alpha1.Binding{ @@ -289,9 +289,11 @@ func generateWorkspaceBindings(spaceBindings []toolchainv1alpha1.SpaceBinding) ( Role: spaceBinding.Spec.SpaceRole, AvailableActions: []string{}, } + spaceBindingSpaceName := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey] sbrName, sbrNameFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] sbrNamespace, sbrNamespaceFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] - if sbrNameFound || sbrNamespaceFound { + // check if spacebinding was generated from SBR on the current space and not on a parentSpace. + if (sbrNameFound || sbrNamespaceFound) && spaceBindingSpaceName == space.GetName() { if sbrName == "" { // small corner case where the SBR name for some reason is not present as labels on the sb. return nil, fmt.Errorf("SpaceBindingRequest name not found on binding: %s", spaceBinding.GetName()) @@ -306,10 +308,13 @@ func generateWorkspaceBindings(spaceBindings []toolchainv1alpha1.SpaceBinding) ( Name: sbrName, Namespace: sbrNamespace, } - } else { - // this is a binding that was inherited from a parent space, - // it can only be overridden by another SpaceBindingRequest containing the same MUR but different role. + } else if spaceBindingSpaceName != space.GetName() { + // this is a binding that was inherited from a parent space, since the name on the spacebinding label doesn't match with the current space name. + // It can only be overridden by another SpaceBindingRequest containing the same MUR but different role. binding.AvailableActions = []string{OverrideBindingAction} + } else { + // this is a system generated SpaceBinding, so it cannot be managed by workspace users. + binding.AvailableActions = []string{} } bindings = append(bindings, binding) } diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index 57b150b4..44b6f977 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -50,9 +50,15 @@ func TestSpaceLister(t *testing.T) { spaceNotProvisionedYet.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] = "" // spacebinding associated with SpaceBindingRequest - spaceBindingWithSBR := fake.NewSpaceBinding("foodlover-sb-from-sbr", "foodlover", "movielover", "maintainer") - spaceBindingWithSBR.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] = "foodlover-sbr" - spaceBindingWithSBR.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] = "movielover-tenant" + spaceBindingWithSBRonMovieLover := fake.NewSpaceBinding("foodlover-sb-from-sbr-on-movielover", "foodlover", "movielover", "maintainer") + spaceBindingWithSBRonMovieLover.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] = "foodlover-sbr" + spaceBindingWithSBRonMovieLover.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] = "movielover-tenant" + + // spacebinding associated with SpaceBindingRequest on a dancelover, + // which is also the parentSpace of foodlover + spaceBindingWithSBRonDanceLover := fake.NewSpaceBinding("animelover-sb-from-sbr-on-dancelover", "animelover", "dancelover", "viewer") + spaceBindingWithSBRonDanceLover.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] = "animelover-sbr" + spaceBindingWithSBRonDanceLover.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey] = "dancelover-tenant" // spacebinding with SpaceBindingRequest but name is missing spaceBindingWithInvalidSBRName := fake.NewSpaceBinding("carlover-sb-from-sbr", "carlover", "animelover", "viewer") @@ -81,7 +87,8 @@ func TestSpaceLister(t *testing.T) { fake.NewSpaceBinding("racer-sb", "racinglover", "racinglover", "admin"), fake.NewSpaceBinding("anime-sb", "animelover", "animelover", "admin"), fake.NewSpaceBinding("car-sb", "carlover", "carlover", "admin"), - spaceBindingWithSBR, + spaceBindingWithSBRonMovieLover, + spaceBindingWithSBRonDanceLover, spaceBindingWithInvalidSBRName, spaceBindingWithInvalidSBRNamespace, @@ -225,10 +232,19 @@ func TestSpaceLister(t *testing.T) { }, ), commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "animelover", + Role: "viewer", + AvailableActions: []string{"update", "delete"}, + BindingRequest: toolchainv1alpha1.BindingRequest{ // animelover was granted access to dancelover workspace using SpaceBindingRequest + Name: "animelover-sbr", + Namespace: "dancelover-tenant", + }, + }, { MasterUserRecord: "dancelover", Role: "admin", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, }), ), @@ -247,13 +263,13 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "dancelover", Role: "other", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, { MasterUserRecord: "foodlover", Role: "maintainer", AvailableActions: []string{"update", "delete"}, - BindingRequest: toolchainv1alpha1.BindingRequest{ + BindingRequest: toolchainv1alpha1.BindingRequest{ // foodlover was granted access to movielover workspace using SpaceBindingRequest Name: "foodlover-sbr", Namespace: "movielover-tenant", }, @@ -261,7 +277,7 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "movielover", Role: "admin", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, }), ), @@ -277,6 +293,11 @@ func TestSpaceLister(t *testing.T) { "admin", "viewer", }), commonproxy.WithBindings([]toolchainv1alpha1.Binding{ + { + MasterUserRecord: "animelover", + Role: "viewer", // animelover was granted access via SBR , but on the parentSpace, + AvailableActions: []string{"override"}, // since the binding is inherited from parent space, then it can only be overridden + }, { MasterUserRecord: "dancelover", Role: "admin", // dancelover is admin since it's admin on the parent space, @@ -300,7 +321,7 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "dancelover", Role: "other", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, { MasterUserRecord: "foodlover", @@ -314,7 +335,7 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "movielover", Role: "admin", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, }), ), @@ -340,10 +361,10 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "dancelover", Role: "other", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, { - MasterUserRecord: "foodlover", + MasterUserRecord: "foodlover", // foodlover was granted access to movielover workspace using SpaceBindingRequest Role: "maintainer", AvailableActions: []string{"update", "delete"}, BindingRequest: toolchainv1alpha1.BindingRequest{ @@ -354,7 +375,7 @@ func TestSpaceLister(t *testing.T) { { MasterUserRecord: "movielover", Role: "admin", - AvailableActions: []string{"override"}, + AvailableActions: []string(nil), // this is system generated so no actions for the user }, }), ), From e8eee83db6691d4923771242f81bf01d7ac41e37 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Tue, 10 Oct 2023 11:30:15 +0200 Subject: [PATCH 21/26] avoid checking for multiple spacebindings for user --- pkg/proxy/handlers/spacelister.go | 21 ++++++++------------- pkg/proxy/handlers/spacelister_test.go | 17 ----------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index c965128a..1da3364d 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -121,16 +121,11 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor } // check if user has access to this workspace - userBindings := filterUserSpaceBindings(userSignup.CompliantUsername, allSpaceBindings) - if len(userBindings) == 0 { + userBinding := filterUserSpaceBinding(userSignup.CompliantUsername, allSpaceBindings) + if userBinding == nil { // let's only log the issue and consider this as not found - ctx.Logger().Error(fmt.Sprintf("expected only 1 spacebinding, got 0 for user %s and workspace %s", userSignup.CompliantUsername, workspaceName)) + ctx.Logger().Error(fmt.Sprintf("expected 1 spacebinding, got 0 for user %s and workspace %s", userSignup.CompliantUsername, workspaceName)) return nil, nil - } else if len(userBindings) > 1 { - // internal server error - cause := fmt.Errorf("expected only 1 spacebinding, got %d for user %s and workspace %s", len(userBindings), userSignup.CompliantUsername, workspaceName) - ctx.Logger().Error(cause.Error()) - return nil, cause } // build the Bindings list with the available actions // this field is populated only for the GET workspace request @@ -147,7 +142,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor return nil, err } - return createWorkspaceObject(userSignup.Name, space, &userBindings[0], + return createWorkspaceObject(userSignup.Name, space, userBinding, commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)), commonproxy.WithBindings(bindings), ), nil @@ -269,14 +264,14 @@ func errorResponse(ctx echo.Context, err *apierrors.StatusError) error { return json.NewEncoder(ctx.Response().Writer).Encode(err.ErrStatus) } -// filterUserSpaceBindings returns all the spacebindings for a given username -func filterUserSpaceBindings(username string, allSpaceBindings []toolchainv1alpha1.SpaceBinding) (outputBindings []toolchainv1alpha1.SpaceBinding) { +// filterUserSpaceBinding returns the spacebinding for a given username, or nil if not found +func filterUserSpaceBinding(username string, allSpaceBindings []toolchainv1alpha1.SpaceBinding) *toolchainv1alpha1.SpaceBinding { for _, binding := range allSpaceBindings { if binding.Spec.MasterUserRecord == username { - outputBindings = append(outputBindings, binding) + return &binding } } - return outputBindings + return nil } // generateWorkspaceBindings generates the bindings list starting from the spacebindings found on a given space resource and an all parent spaces. diff --git a/pkg/proxy/handlers/spacelister_test.go b/pkg/proxy/handlers/spacelister_test.go index 44b6f977..23cf4d69 100644 --- a/pkg/proxy/handlers/spacelister_test.go +++ b/pkg/proxy/handlers/spacelister_test.go @@ -396,23 +396,6 @@ func TestSpaceLister(t *testing.T) { }, expectedWorkspace: "dancelover", }, - "too many spacebindings for user": { - username: "dance.lover", - expectedWs: []toolchainv1alpha1.Workspace{}, - expectedErr: "Internal error occurred: expected only 1 spacebinding, got 2 for user dancelover and workspace dancelover", - expectedErrCode: 500, - overrideInformerFunc: func() service.InformerService { - listSpaceBindingFunc := func(reqs ...labels.Requirement) ([]toolchainv1alpha1.SpaceBinding, error) { - // let's return more than 1 spacebinding to trigger the error - return []toolchainv1alpha1.SpaceBinding{ - *fake.NewSpaceBinding("dancer-sb1", "dancelover", "dancelover", "admin"), - *fake.NewSpaceBinding("dancer-sb2", "dancelover", "dancelover", "other"), - }, nil - } - return getFakeInformerService(fakeClient, WithListSpaceBindingFunc(listSpaceBindingFunc))() - }, - expectedWorkspace: "dancelover", - }, "get signup error": { username: "dance.lover", expectedWs: []toolchainv1alpha1.Workspace{}, From 075917aacdfe0aa8ae6af5dd051cd2fec7c8cb98 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Tue, 10 Oct 2023 14:28:18 +0200 Subject: [PATCH 22/26] update api --- go.mod | 4 +--- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 715caa4f..a2b94c11 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/aws/aws-sdk-go v1.44.100 - github.com/codeready-toolchain/api v0.0.0-20230918195153-739e8fb09a33 + github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3 github.com/go-logr/logr v1.2.3 github.com/gofrs/uuid v4.2.0+incompatible @@ -146,5 +146,3 @@ require ( ) replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e - -replace github.com/codeready-toolchain/api => github.com/mfrancisc/api v0.0.0-20231009110929-3412d406675e diff --git a/go.sum b/go.sum index 87922f6c..cf6644de 100644 --- a/go.sum +++ b/go.sum @@ -111,6 +111,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a h1:UucbKqQ0bz9xe/Hr6kbrJkPK0YzCn2bdFwGme5rCfuU= +github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -369,8 +371,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mfrancisc/api v0.0.0-20231009110929-3412d406675e h1:X7Cous9+l2Ju7t8IPEtebiOuF8OsZRmUIZlt4tvFFvc= -github.com/mfrancisc/api v0.0.0-20231009110929-3412d406675e/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e h1:P4C77qKcRLx9BJ8vnYaX6MC84SUCrz6EldhhiIazHHA= github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= From 819cd5f4a87807e65ed96756bcfeb1ede16eaca5 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 11 Oct 2023 15:14:40 +0200 Subject: [PATCH 23/26] Update pkg/proxy/handlers/spacelister.go Co-authored-by: Matous Jobanek --- pkg/proxy/handlers/spacelister.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index 1da3364d..f911018c 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -110,10 +110,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor } return s.GetInformerServiceFunc().ListSpaceBindings(*spaceSelector) } - getSpaceFunc := func(spaceName string) (*toolchainv1alpha1.Space, error) { - return s.GetInformerServiceFunc().GetSpace(spaceName) - } - spaceBindingLister := spacebinding.NewLister(listSpaceBindingsFunc, getSpaceFunc) + spaceBindingLister := spacebinding.NewLister(listSpaceBindingsFunc, s.GetInformerServiceFunc().GetSpace) allSpaceBindings, err := spaceBindingLister.ListForSpace(space, []toolchainv1alpha1.SpaceBinding{}) if err != nil { ctx.Logger().Error(err, "failed to list space bindings") From 6ae41ccad7d878c3fccf4e78d9a87513c86412a9 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 11 Oct 2023 15:15:08 +0200 Subject: [PATCH 24/26] Update pkg/proxy/handlers/spacelister.go Co-authored-by: Matous Jobanek --- pkg/proxy/handlers/spacelister.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/proxy/handlers/spacelister.go b/pkg/proxy/handlers/spacelister.go index f911018c..71b5492f 100644 --- a/pkg/proxy/handlers/spacelister.go +++ b/pkg/proxy/handlers/spacelister.go @@ -121,7 +121,7 @@ func (s *SpaceLister) GetUserWorkspace(ctx echo.Context) (*toolchainv1alpha1.Wor userBinding := filterUserSpaceBinding(userSignup.CompliantUsername, allSpaceBindings) if userBinding == nil { // let's only log the issue and consider this as not found - ctx.Logger().Error(fmt.Sprintf("expected 1 spacebinding, got 0 for user %s and workspace %s", userSignup.CompliantUsername, workspaceName)) + ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", userSignup.CompliantUsername, workspaceName)) return nil, nil } // build the Bindings list with the available actions From e433e7fd8481218be427cb93bfcbea97cdfde959 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Wed, 11 Oct 2023 15:41:16 +0200 Subject: [PATCH 25/26] update api and common --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a2b94c11..89cc8c9f 100644 --- a/go.mod +++ b/go.mod @@ -145,4 +145,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e +replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20231011125252-0299bfd1dcf5 diff --git a/go.sum b/go.sum index cf6644de..f486244b 100644 --- a/go.sum +++ b/go.sum @@ -371,8 +371,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e h1:P4C77qKcRLx9BJ8vnYaX6MC84SUCrz6EldhhiIazHHA= -github.com/mfrancisc/toolchain-common v0.0.0-20231002145157-94054ae52f2e/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= +github.com/mfrancisc/toolchain-common v0.0.0-20231011125252-0299bfd1dcf5 h1:RMCxWiA0wmFdp4K83M1Etomi5IIHcwL+XpDOaYiwKaw= +github.com/mfrancisc/toolchain-common v0.0.0-20231011125252-0299bfd1dcf5/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= From 105c90a3f5cc10781a6aa140fad0c883c199c528 Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Thu, 12 Oct 2023 09:01:11 +0200 Subject: [PATCH 26/26] update common --- go.mod | 4 +--- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index bd9d93d1..a6717390 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/aws/aws-sdk-go v1.44.100 github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a - github.com/codeready-toolchain/toolchain-common v0.0.0-20230710095440-719b09376de3 + github.com/codeready-toolchain/toolchain-common v0.0.0-20231012065805-a23f3cfa676d github.com/go-logr/logr v1.2.3 github.com/gofrs/uuid v4.2.0+incompatible github.com/pkg/errors v0.9.1 @@ -144,5 +144,3 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) - -replace github.com/codeready-toolchain/toolchain-common => github.com/mfrancisc/toolchain-common v0.0.0-20231011125252-0299bfd1dcf5 diff --git a/go.sum b/go.sum index a822de20..39c4178d 100644 --- a/go.sum +++ b/go.sum @@ -113,6 +113,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a h1:UucbKqQ0bz9xe/Hr6kbrJkPK0YzCn2bdFwGme5rCfuU= github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a/go.mod h1:nn3W6eKb9PFIVwSwZW7wDeLACMBOwAV+4kddGuN+ARM= +github.com/codeready-toolchain/toolchain-common v0.0.0-20231012065805-a23f3cfa676d h1:gQy0fpfCjl4XQhoXEQ3NUrvpRp4qKzov5TBKyePuwOM= +github.com/codeready-toolchain/toolchain-common v0.0.0-20231012065805-a23f3cfa676d/go.mod h1:SnZewh0DLwAELKLsW+R6NKaKmiRBuMI1iMYSkfyZG6A= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -371,8 +373,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mfrancisc/toolchain-common v0.0.0-20231011125252-0299bfd1dcf5 h1:RMCxWiA0wmFdp4K83M1Etomi5IIHcwL+XpDOaYiwKaw= -github.com/mfrancisc/toolchain-common v0.0.0-20231011125252-0299bfd1dcf5/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=