@@ -30,6 +30,7 @@ import (
3030
3131const (
3232 workspaceIndex = "workspaceIndex"
33+ ipAddressIndex = "ipAddressIndex"
3334)
3435
3536// getPortStr extracts the port part from a given URL string. Returns "" if parsing fails or port is not specified.
@@ -77,6 +78,15 @@ func NewCRDWorkspaceInfoProvider(client client.Client, scheme *runtime.Scheme) (
7778
7879 return nil , xerrors .Errorf ("object is not a WorkspaceInfo" )
7980 },
81+ ipAddressIndex : func (obj interface {}) ([]string , error ) {
82+ if workspaceInfo , ok := obj .(* common.WorkspaceInfo ); ok {
83+ if workspaceInfo .IPAddress == "" {
84+ return nil , nil
85+ }
86+ return []string {workspaceInfo .IPAddress }, nil
87+ }
88+ return nil , xerrors .Errorf ("object is not a WorkspaceInfo" )
89+ },
8090 }
8191 contextIndexers := cache.Indexers {
8292 workspaceIndex : func (obj interface {}) ([]string , error ) {
@@ -96,29 +106,65 @@ func NewCRDWorkspaceInfoProvider(client client.Client, scheme *runtime.Scheme) (
96106 }, nil
97107}
98108
99- // WorkspaceInfo return the WorkspaceInfo available for the given workspaceID.
109+ // WorkspaceInfo returns the WorkspaceInfo for the given workspaceID.
110+ // It performs validation to ensure the workspace is unique and properly associated with its IP address.
100111func (r * CRDWorkspaceInfoProvider ) WorkspaceInfo (workspaceID string ) * common.WorkspaceInfo {
101112 workspaces , err := r .store .ByIndex (workspaceIndex , workspaceID )
102113 if err != nil {
103114 return nil
104115 }
105116
106- if len (workspaces ) >= 1 {
107- if len (workspaces ) != 1 {
108- log .Warnf ("multiple instances (%d) for workspace %s" , len (workspaces ), workspaceID )
109- }
117+ if len (workspaces ) == 0 {
118+ return nil
119+ }
110120
111- sort . Slice ( workspaces , func ( i , j int ) bool {
112- a := workspaces [ i ].( * common. WorkspaceInfo )
113- b := workspaces [ j ].( * common. WorkspaceInfo )
121+ if len ( workspaces ) > 1 {
122+ log . WithField ( "workspaceID" , workspaceID ). WithField ( "instanceCount" , len ( workspaces )). Warn ( "multiple workspace instances found" )
123+ }
114124
115- return a .StartedAt .After (b .StartedAt )
116- })
125+ sort .Slice (workspaces , func (i , j int ) bool {
126+ a := workspaces [i ].(* common.WorkspaceInfo )
127+ b := workspaces [j ].(* common.WorkspaceInfo )
128+ return a .StartedAt .After (b .StartedAt )
129+ })
117130
118- return workspaces [0 ].(* common.WorkspaceInfo )
131+ wsInfo := workspaces [0 ].(* common.WorkspaceInfo )
132+
133+ if wsInfo .IPAddress == "" {
134+ return wsInfo
135+ }
136+
137+ wsInfos , err := r .workspacesInfoByIPAddress (wsInfo .IPAddress )
138+ if err != nil {
139+ log .WithError (err ).WithField ("workspaceID" , workspaceID ).WithField ("ipAddress" , wsInfo .IPAddress ).Error ("failed to get workspaces by IP address" )
140+ return nil
141+ }
142+
143+ if len (wsInfos ) > 1 {
144+ log .WithField ("workspaceID" , workspaceID ).WithField ("ipAddress" , wsInfo .IPAddress ).WithField ("workspaceCount" , len (wsInfos )).Warn ("multiple workspaces found for IP address" )
145+ return nil
146+ }
147+
148+ if len (wsInfos ) == 1 && wsInfos [0 ].WorkspaceID != workspaceID {
149+ log .WithField ("workspaceID" , workspaceID ).WithField ("ipAddress" , wsInfo .IPAddress ).WithField ("foundWorkspaceID" , wsInfos [0 ].WorkspaceID ).Warn ("workspace IP address conflict detected" )
150+ return nil
151+ }
152+
153+ return wsInfo
154+ }
155+
156+ func (r * CRDWorkspaceInfoProvider ) workspacesInfoByIPAddress (ipAddress string ) ([]* common.WorkspaceInfo , error ) {
157+ workspaces := make ([]* common.WorkspaceInfo , 0 )
158+
159+ objs , err := r .store .ByIndex (ipAddressIndex , ipAddress )
160+ if err != nil {
161+ return nil , err
162+ }
163+ for _ , w := range objs {
164+ workspaces = append (workspaces , w .(* common.WorkspaceInfo ))
119165 }
120166
121- return nil
167+ return workspaces , nil
122168}
123169
124170func (r * CRDWorkspaceInfoProvider ) AcquireContext (ctx context.Context , workspaceID string , port string ) (context.Context , string , error ) {
0 commit comments