@@ -4,7 +4,7 @@ import { getCluster } from '../../../cluster';
4
4
import { ApiError , QueryParameters } from '../../apiProxy' ;
5
5
import { KubeObject , KubeObjectInterface } from '../../KubeObject' ;
6
6
import { clusterFetch } from './fetch' ;
7
- import { KubeList , KubeListUpdateEvent } from './KubeList' ;
7
+ import { KubeListUpdateEvent } from './KubeList' ;
8
8
import { KubeObjectEndpoint } from './KubeObjectEndpoint' ;
9
9
import { makeUrl } from './makeUrl' ;
10
10
import { useWebSocket } from './webSocket' ;
@@ -159,9 +159,13 @@ export function useKubeObject<K extends KubeObject>({
159
159
* @throws Error
160
160
* When no endpoints are working
161
161
*/
162
- const getWorkingEndpoint = async ( endpoints : KubeObjectEndpoint [ ] , cluster : string ) => {
162
+ const getWorkingEndpoint = async (
163
+ endpoints : KubeObjectEndpoint [ ] ,
164
+ cluster : string ,
165
+ namespace ?: string
166
+ ) => {
163
167
const promises = endpoints . map ( endpoint => {
164
- return clusterFetch ( KubeObjectEndpoint . toUrl ( endpoint ) , {
168
+ return clusterFetch ( KubeObjectEndpoint . toUrl ( endpoint , namespace ) , {
165
169
method : 'GET' ,
166
170
cluster : cluster ?? getCluster ( ) ?? '' ,
167
171
} ) . then ( it => {
@@ -179,225 +183,22 @@ const getWorkingEndpoint = async (endpoints: KubeObjectEndpoint[], cluster: stri
179
183
*
180
184
* @params endpoints - List of possible endpoints
181
185
*/
182
- const useEndpoints = ( endpoints : KubeObjectEndpoint [ ] , cluster : string ) => {
186
+ export const useEndpoints = (
187
+ endpoints : KubeObjectEndpoint [ ] ,
188
+ cluster ?: string ,
189
+ namespace ?: string
190
+ ) => {
183
191
const { data : endpoint } = useQuery ( {
184
- enabled : endpoints . length > 1 ,
192
+ enabled : endpoints . length > 1 && cluster !== undefined ,
185
193
queryKey : [ 'endpoints' , endpoints ] ,
186
194
queryFn : ( ) =>
187
- getWorkingEndpoint ( endpoints , cluster )
195
+ getWorkingEndpoint ( endpoints , cluster ! , namespace )
188
196
. then ( endpoints => endpoints )
189
197
. catch ( ( ) => null ) ,
190
198
} ) ;
191
199
200
+ if ( cluster === null || cluster === undefined ) return undefined ;
192
201
if ( endpoints . length === 1 ) return endpoints [ 0 ] ;
193
202
194
203
return endpoint ;
195
204
} ;
196
-
197
- /**
198
- * Returns a list of Kubernetes objects and watches for changes
199
- *
200
- * @private please use useKubeObjectList.
201
- */
202
- function _useKubeObjectList < K extends KubeObject > ( {
203
- kubeObjectClass,
204
- namespace,
205
- cluster : maybeCluster ,
206
- queryParams,
207
- } : {
208
- /** Class to instantiate the object with */
209
- kubeObjectClass : ( new ( ...args : any ) => K ) & typeof KubeObject < any > ;
210
- /** Object list namespace */
211
- namespace ?: string ;
212
- /** Object list cluster */
213
- cluster ?: string ;
214
- queryParams ?: QueryParameters ;
215
- } ) : [ Array < K > | null , ApiError | null ] & QueryListResponse < KubeList < K > , K , ApiError > {
216
- const cluster = maybeCluster ?? getCluster ( ) ?? '' ;
217
- const endpoint = useEndpoints ( kubeObjectClass . apiEndpoint . apiInfo , cluster ) ;
218
-
219
- const cleanedUpQueryParams = Object . fromEntries (
220
- Object . entries ( queryParams ?? { } ) . filter ( ( [ , value ] ) => value !== undefined && value !== '' )
221
- ) ;
222
-
223
- const queryKey = useMemo (
224
- ( ) => [ 'list' , cluster , endpoint , namespace ?? '' , cleanedUpQueryParams ] ,
225
- [ endpoint , namespace , cleanedUpQueryParams ]
226
- ) ;
227
-
228
- const client = useQueryClient ( ) ;
229
- const query = useQuery < KubeList < any > | null | undefined , ApiError > ( {
230
- enabled : ! ! endpoint ,
231
- placeholderData : null ,
232
- queryKey,
233
- queryFn : async ( ) => {
234
- if ( ! endpoint ) return ;
235
- const list : KubeList < any > = await clusterFetch (
236
- makeUrl ( [ KubeObjectEndpoint . toUrl ( endpoint ! , namespace ) ] , cleanedUpQueryParams ) ,
237
- {
238
- cluster,
239
- }
240
- ) . then ( it => it . json ( ) ) ;
241
- list . items = list . items . map ( item => {
242
- const itm = new kubeObjectClass ( { ...item , kind : list . kind . replace ( 'List' , '' ) } ) ;
243
- itm . cluster = cluster ;
244
- return itm ;
245
- } ) ;
246
-
247
- return list ;
248
- } ,
249
- } ) ;
250
-
251
- const items : Array < K > | null = query . error ? null : query . data ?. items ?? null ;
252
- const data : KubeList < K > | null = query . error ? null : query . data ?? null ;
253
-
254
- useWebSocket < KubeListUpdateEvent < K > > ( {
255
- url : ( ) =>
256
- makeUrl ( [ KubeObjectEndpoint . toUrl ( endpoint ! ) ] , {
257
- ...cleanedUpQueryParams ,
258
- watch : 1 ,
259
- resourceVersion : data ! . metadata . resourceVersion ,
260
- } ) ,
261
- cluster,
262
- enabled : ! ! endpoint && ! ! data ,
263
- onMessage ( update ) {
264
- client . setQueryData ( queryKey , ( oldList : any ) => {
265
- const newList = KubeList . applyUpdate ( oldList , update , kubeObjectClass ) ;
266
- return newList ;
267
- } ) ;
268
- } ,
269
- } ) ;
270
-
271
- // @ts -ignore
272
- return {
273
- items,
274
- data,
275
- error : query . error ,
276
- isError : query . isError ,
277
- isLoading : query . isLoading ,
278
- isFetching : query . isFetching ,
279
- isSuccess : query . isSuccess ,
280
- status : query . status ,
281
- * [ Symbol . iterator ] ( ) : ArrayIterator < ApiError | K [ ] | null > {
282
- yield items ;
283
- yield query . error ;
284
- } ,
285
- } ;
286
- }
287
-
288
- /**
289
- * Returns a combined list of Kubernetes objects and watches for changes from the clusters given.
290
- */
291
- export function useKubeObjectList < K extends KubeObject > ( {
292
- kubeObjectClass,
293
- namespace,
294
- cluster,
295
- clusters,
296
- queryParams,
297
- } : {
298
- /** Class to instantiate the object with */
299
- kubeObjectClass : ( new ( ...args : any ) => K ) & typeof KubeObject < any > ;
300
- /** Object list namespace */
301
- namespace ?: string ;
302
- cluster ?: string ;
303
- /** Object list clusters */
304
- clusters ?: string [ ] ;
305
- queryParams ?: QueryParameters ;
306
- } ) : [ Array < K > | null , ApiError | null ] & QueryListResponse < KubeList < K > , K , ApiError > {
307
- if ( clusters && clusters . length > 0 ) {
308
- return _useKubeObjectLists ( {
309
- kubeObjectClass,
310
- namespace,
311
- clusters : clusters ,
312
- queryParams,
313
- } ) ;
314
- } else {
315
- return _useKubeObjectList ( {
316
- kubeObjectClass,
317
- namespace,
318
- cluster : cluster ,
319
- queryParams,
320
- } ) ;
321
- }
322
- }
323
-
324
- /**
325
- * Returns a combined list of Kubernetes objects and watches for changes from the clusters given.
326
- *
327
- * @private please use useKubeObjectList
328
- */
329
- function _useKubeObjectLists < K extends KubeObject > ( {
330
- kubeObjectClass,
331
- namespace,
332
- clusters,
333
- queryParams,
334
- } : {
335
- /** Class to instantiate the object with */
336
- kubeObjectClass : ( new ( ...args : any ) => K ) & typeof KubeObject < any > ;
337
- /** Object list namespace */
338
- namespace ?: string ;
339
- /** Object list clusters */
340
- clusters : string [ ] ;
341
- queryParams ?: QueryParameters ;
342
- } ) : [ Array < K > | null , ApiError | null ] & QueryListResponse < KubeList < K > , K , ApiError > {
343
- const clusterResults : Record < string , ReturnType < typeof useKubeObjectList < K > > > = { } ;
344
-
345
- for ( const cluster of clusters ) {
346
- clusterResults [ cluster ] = _useKubeObjectList ( {
347
- kubeObjectClass,
348
- namespace,
349
- cluster : cluster || undefined ,
350
- queryParams,
351
- } ) ;
352
- }
353
-
354
- let items = null ;
355
- for ( const cluster of clusters ) {
356
- if ( items === null ) {
357
- items = clusterResults [ cluster ] . items ;
358
- } else {
359
- items = items . concat ( clusterResults [ cluster ] . items ?? [ ] ) ;
360
- }
361
- }
362
-
363
- // data makes no sense really for multiple clusters, but useful for single cluster?
364
- const data =
365
- clusters . map ( cluster => clusterResults [ cluster ] . data ) . find ( it => it !== null ) ?? null ;
366
- const error =
367
- clusters . map ( cluster => clusterResults [ cluster ] . error ) . find ( it => it !== null ) ?? null ;
368
- const isError = clusters . some ( cluster => clusterResults [ cluster ] . isError ) ;
369
- const isLoading = clusters . some ( cluster => clusterResults [ cluster ] . isLoading ) ;
370
- const isFetching = clusters . some ( cluster => clusterResults [ cluster ] . isFetching ) ;
371
- const isSuccess = clusters . every ( cluster => clusterResults [ cluster ] . isSuccess ) ;
372
- // status makes no sense really for multiple clusters, but maybe useful for single cluster?
373
- const status =
374
- clusters . map ( cluster => clusterResults [ cluster ] . status ) . find ( it => it !== null ) ?? 'pending' ;
375
-
376
- let clusterErrors : Record < string , ApiError | null > | null = { } ;
377
- clusters . forEach ( cluster => {
378
- if ( clusterErrors && clusterResults [ cluster ] ?. error !== null ) {
379
- clusterErrors [ cluster ] = clusterResults [ cluster ] . error ;
380
- }
381
- } ) ;
382
- if ( Object . keys ( clusterErrors ) . length === 0 ) {
383
- clusterErrors = null ;
384
- }
385
-
386
- // @ts -ignore
387
- return {
388
- items,
389
- data,
390
- error,
391
- isError,
392
- isLoading,
393
- isFetching,
394
- isSuccess,
395
- status,
396
- * [ Symbol . iterator ] ( ) : ArrayIterator < ApiError | K [ ] | null > {
397
- yield items ;
398
- yield error ;
399
- } ,
400
- clusterResults,
401
- clusterErrors,
402
- } ;
403
- }
0 commit comments