Skip to content

Commit

Permalink
feat: Implement public API that will open SpaceBindings to end users …
Browse files Browse the repository at this point in the history
…through proxy part 2 (#350)

* add bindings list to workspace api
---------

Co-authored-by: Alexey Kazakov <alkazako@redhat.com>
Co-authored-by: Matous Jobanek <mjobanek@redhat.com>
  • Loading branch information
3 people authored Oct 12, 2023
1 parent a305bf9 commit 9dd5dd6
Show file tree
Hide file tree
Showing 5 changed files with 364 additions and 95 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ 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/toolchain-common v0.0.0-20231002120847-bf3a59c8351b
github.com/codeready-toolchain/api v0.0.0-20231010090546-098b27b43b3a
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
Expand Down
20 changes: 16 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -107,10 +111,10 @@ 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/codeready-toolchain/toolchain-common v0.0.0-20231002120847-bf3a59c8351b h1:3nk69kWcILOiu6Ul9DZZTRmx4pItVit+9uOAmjrYCfM=
github.com/codeready-toolchain/toolchain-common v0.0.0-20231002120847-bf3a59c8351b/go.mod h1:o/JGPWZ/9rVh/np0tcaPRXnreZ+X743o0Gxp1eP62/w=
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=
Expand Down Expand Up @@ -293,6 +297,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=
Expand Down Expand Up @@ -370,6 +375,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
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=
Expand Down Expand Up @@ -408,14 +415,17 @@ github.com/prometheus/common v0.40.0 h1:Afz7EVRqGg2Mqqf4JuF9vdvp1pi220m55Pi9T2Jn
github.com/prometheus/common v0.40.0/go.mod h1:L65ZJPSmfn/UBWLQIHV7dBrKFidB/wPlF1y5TlSt9OE=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
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/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
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=
Expand Down Expand Up @@ -979,13 +989,15 @@ 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=
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=
Expand Down
150 changes: 102 additions & 48 deletions pkg/proxy/handlers/spacelister.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -14,8 +16,8 @@ import (
"github.com/codeready-toolchain/registration-service/pkg/metrics"
"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"
"time"

"github.com/labstack/echo/v4"
errs "github.com/pkg/errors"
Expand All @@ -26,6 +28,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 SpaceBindingRequest 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
Expand Down Expand Up @@ -71,6 +82,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 {
Expand All @@ -84,38 +96,53 @@ 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)
}
spaceBindingLister := spacebinding.NewLister(listSpaceBindingsFunc, s.GetInformerServiceFunc().GetSpace)
allSpaceBindings, err := spaceBindingLister.ListForSpace(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
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("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
// this field is populated only for the GET workspace request
// -------------
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)
if err != nil {
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, userBinding,
commonproxy.WithAvailableRoles(getRolesFromNSTemplateTier(nsTemplateTier)),
commonproxy.WithBindings(bindings),
), nil
}

func (s *SpaceLister) ListUserWorkspaces(ctx echo.Context) ([]toolchainv1alpha1.Workspace, error) {
Expand Down Expand Up @@ -151,38 +178,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 {
Expand Down Expand Up @@ -265,3 +260,62 @@ 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)
}

// 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 {
return &binding
}
}
return nil
}

// 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) {
var bindings []toolchainv1alpha1.Binding
for _, spaceBinding := range spaceBindings {
binding := toolchainv1alpha1.Binding{
MasterUserRecord: spaceBinding.Spec.MasterUserRecord,
Role: spaceBinding.Spec.SpaceRole,
AvailableActions: []string{},
}
spaceBindingSpaceName := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingSpaceLabelKey]
sbrName, sbrNameFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey]
sbrNamespace, sbrNamespaceFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey]
// 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())
}
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 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)
}

// 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, nil
}
Loading

0 comments on commit 9dd5dd6

Please sign in to comment.