Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit 8d98d15

Browse files
committed
fix(plugins/plugin-kubectl): kubectl get table with mix of existing and non-existing
Fixes #4492
1 parent e351a5f commit 8d98d15

File tree

6 files changed

+60
-17
lines changed

6 files changed

+60
-17
lines changed

packages/core/src/webapp/models/table.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 IBM Corporation
2+
* Copyright 2019-2020 IBM Corporation
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,6 +32,9 @@ export class Row {
3232

3333
nameDom?: Element
3434

35+
/** does this row represent a recently deleted resource? */
36+
isDeleted?: boolean
37+
3538
type?: string
3639

3740
packageName?: string

plugins/plugin-kubectl/src/controller/kubectl/exec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 IBM Corporation
2+
* Copyright 2019-2020 IBM Corporation
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -191,8 +191,7 @@ export async function exec<O extends KubeOptions>(
191191
}
192192
})
193193
} else {
194-
const response = await doExecWithoutPty(args, prepare, exec)
195-
return response
194+
return doExecWithoutPty(args, prepare, exec)
196195
}
197196
}
198197

plugins/plugin-kubectl/src/controller/kubectl/get.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 IBM Corporation
2+
* Copyright 2019-2020 IBM Corporation
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -194,14 +194,15 @@ export const doGet = (command: string) =>
194194
}
195195

196196
// first, we do the raw exec of the given command
197-
const fullKind = isTableRequest(args)
197+
const isTableReq = isTableRequest(args)
198+
const fullKind = isTableReq
198199
? getKind(command, args, args.argvNoOptions[args.argvNoOptions.indexOf('get') + 1])
199200
: undefined
200201
const response = await rawGet(args, command)
201202

202203
if (isKubeTableResponse(response)) {
203204
return response
204-
} else if (response.content.code !== 0) {
205+
} else if (response.content.code !== 0 && !isTableReq && response.content.stdout.length === 0) {
205206
// raw exec yielded an error!
206207
const err: CodedError = new Error(response.content.stderr)
207208
err.code = response.content.code
@@ -211,7 +212,7 @@ export const doGet = (command: string) =>
211212
} else if (isEntityRequest(args)) {
212213
// case 1: get-as-entity
213214
return doGetAsEntity(args, response)
214-
} else if (isTableRequest(args)) {
215+
} else if (isTableReq) {
215216
// case 2: get-as-table
216217
return doGetAsTable(command, args, response, undefined, await fullKind)
217218
} else {

plugins/plugin-kubectl/src/controller/kubectl/raw.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ export const doNativeExec = (args: Arguments): Promise<RawResponse> =>
8080
debug('exec stderr', stderr)
8181
}
8282

83-
const noResources = stderr.match(/no resources found/i)
84-
if (code !== 0 || noResources) {
83+
const noResources = /no resources found/i.test(stderr)
84+
if (stdout.length === 0 && (code !== 0 || noResources)) {
8585
const message = stderr
86-
const fileNotFound = message.match(/error: the path/)
86+
const fileNotFound = /error: the path/.test(message)
8787
const codeForREPL =
88-
noResources || message.match(/not found/i) || message.match(/doesn't have/i)
88+
noResources || /not found/i.test(message) || /doesn't have/i.test(message)
8989
? 404
90-
: message.match(/already exists/i)
90+
: /already exists/i.test(message)
9191
? 409
9292
: fileNotFound
9393
? 412

plugins/plugin-kubectl/src/lib/view/css-for-value.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 IBM Corporation
2+
* Copyright 2018-2020 IBM Corporation
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,6 +29,9 @@ export default {
2929
FAILED: TrafficLight.Red,
3030
DELETING: TrafficLight.Yellow,
3131

32+
// kui manufactured; see formatTable.ts withNotFounds()
33+
Offline: TrafficLight.Red,
34+
3235
// pod lifecycle
3336
'Init:0/1': TrafficLight.Yellow,
3437
PodScheduled: TrafficLight.Yellow,

plugins/plugin-kubectl/src/lib/view/formatTable.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 IBM Corporation
2+
* Copyright 2018-2020 IBM Corporation
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -328,6 +328,43 @@ export function isKubeTableResponse(response: KubeTableResponse | RawResponse):
328328
)
329329
}
330330

331+
function withNotFound(table: Table, stderr: string) {
332+
const notFounds = stderr
333+
.split(/\n/)
334+
.filter(_ => /NotFound/.test(_))
335+
.map(_ => _.match(/"([^"]+)" not found/)[1])
336+
337+
if (notFounds.length > 0) {
338+
const statusIdx = table.body.length === 0 ? -1 : table.body[0].attributes.findIndex(_ => /STATUS/i.test(_.key))
339+
const attributes =
340+
table.body.length === 0
341+
? []
342+
: Array(table.body[0].attributes.length)
343+
.fill(undefined)
344+
.map((_, idx) => {
345+
const cell = {} as Cell
346+
if (idx === statusIdx) {
347+
const value = 'Offline'
348+
cell.value = value
349+
cell.tag = tagForKey['STATUS']
350+
cell.outerCSS = outerCSSForKey['STATUS']
351+
cell.css = [cssForKey['STATUS'], cssForValue[value]].join(' ')
352+
}
353+
return cell
354+
})
355+
356+
notFounds.forEach(name => {
357+
table.body.push({
358+
name,
359+
isDeleted: true,
360+
attributes
361+
})
362+
})
363+
}
364+
365+
return table
366+
}
367+
331368
/**
332369
* Display the given string as a REPL table
333370
*
@@ -356,14 +393,14 @@ export const stringToTable = <O extends KubeOptions>(
356393
if (args.execOptions.filter) {
357394
T.body = args.execOptions.filter(T.body)
358395
}
359-
return T
396+
return withNotFound(T, stderr)
360397
} else {
361398
return preTables.map(preTable => {
362399
const T = formatTable(command, verb, entityType, args.parsedOptions, preTable)
363400
if (args.execOptions.filter) {
364401
T.body = args.execOptions.filter(T.body)
365402
}
366-
return T
403+
return withNotFound(T, stderr)
367404
})
368405
}
369406
} else {

0 commit comments

Comments
 (0)