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

Commit 0fbde1b

Browse files
starpitk8s-ci-robot
authored andcommitted
fix(plugins/plugin-kubectl): kubectl direct get may pass through kubeproxy 404s to user
This PR improves the error handling paths, to ensure that 1) http status codes are correctly passed through (there were some gaps); and 2) as an extra level of caution, we check for the specific kubeproxy 404 message part of #7731
1 parent d6838d7 commit 0fbde1b

File tree

4 files changed

+24
-12
lines changed

4 files changed

+24
-12
lines changed

plugins/plugin-kubectl/src/controller/client/direct/errors.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { CodedError, isCodedError, REPL } from '@kui-shell/core'
1919
import URLFormatter from './url'
2020
import { headersForPlainRequest } from './headers'
2121
import { Status, isStatus } from '../../../lib/model/resource'
22-
import { fetchFile, FetchedFile, isReturnedError } from '../../../lib/util/fetch-file'
22+
import { fetchFile, FetchedFile, isReturnedError, ReturnedError } from '../../../lib/util/fetch-file'
2323

2424
type WithErrors = {
2525
errors: CodedError[]
@@ -29,16 +29,16 @@ type WithErrors = {
2929
}
3030

3131
/** See if the given error message is a Kubernetes Status object */
32-
export function tryParseAsStatus(message: string): string | Status {
32+
export function tryParseAsStatus(code: number | string, error: string): ReturnedError | Status {
3333
try {
34-
const obj = JSON.parse(message)
34+
const obj = JSON.parse(error)
3535
if (isStatus(obj)) {
3636
return obj
3737
} else {
38-
return message
38+
return { code, error }
3939
}
4040
} catch (err) {
41-
return message
41+
return { code, error }
4242
}
4343
}
4444

@@ -51,7 +51,11 @@ export default async function handleErrors(
5151
): Promise<WithErrors> {
5252
const withErrors: (string | Buffer | object | CodedError)[] = await Promise.all(
5353
responses.map(async data => {
54-
let errorData = isReturnedError(data) ? tryParseAsStatus(data.error) : isStatus(data) ? data : undefined
54+
let errorData = isReturnedError(data)
55+
? tryParseAsStatus(data.code, data.error)
56+
: isStatus(data)
57+
? data
58+
: undefined
5559
if (errorData) {
5660
if (isStatus(errorData)) {
5761
// if we could not find the requested resource, do some
@@ -89,8 +93,8 @@ export default async function handleErrors(
8993
return error
9094
} else {
9195
// some other random error, i.e. not a Kubernetes Status error
92-
const error: CodedError = new Error(errorData)
93-
error.code = 500
96+
const error: CodedError<number | string> = new Error(errorData.error)
97+
error.code = errorData.code || 500
9498
return error
9599
}
96100
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ export async function get(
196196
try {
197197
response = (await fetchFile(args.REPL, urls, { headers: { accept: 'application/json' } }))[0]
198198
} catch (err) {
199-
response = tryParseAsStatus(err.message)
199+
response = tryParseAsStatus(err.code, err.message)
200200
if (!isStatus(response)) {
201201
throw err
202202
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ async function rawGet(
283283
return response
284284
}
285285
} catch (err) {
286-
if (err.code !== 500 && err.code !== undefined) {
286+
if (err.code !== 500 && err.code !== undefined && !/page not found/.test(err.message)) {
287287
// expected apiServer error, i.e. Kubernetes Status errors
288288
throw err
289289
} else {

plugins/plugin-kubectl/src/lib/util/fetch-file.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,11 @@ export async function _needle(
150150

151151
// internal usage: test kui's error handling of apiServer
152152
if (process.env.TRAVIS_CHAOS_TESTING) {
153-
throw new Error('nope')
153+
// simulate a condition where kuiproxy is not installed on the apiserver
154+
const error: CodedError = new Error('404 page not found')
155+
error.code = 404
156+
error.statusCode = 404
157+
throw error
154158
}
155159

156160
try {
@@ -231,6 +235,7 @@ async function fetchRemote(repl: REPL, url: string, opts?: FetchOptions<BodyData
231235
}
232236

233237
export type ReturnedError = {
238+
code: number | string
234239
error: string
235240
}
236241

@@ -264,7 +269,10 @@ export async function fetchFile(
264269
Object.assign({}, opts, { data: Array.isArray(opts.data) ? opts.data[idx] : opts.data })
265270
).catch(err => {
266271
if (opts && opts.returnErrors) {
267-
return { error: err.message || JSON.stringify(err) }
272+
return {
273+
code: err.code,
274+
error: err.message || JSON.stringify(err)
275+
}
268276
} else throw err
269277
})
270278
} else {

0 commit comments

Comments
 (0)