From b0a6d8d6d67040154abbd27acb91826e2b909de4 Mon Sep 17 00:00:00 2001 From: Mengting Yan Date: Wed, 6 May 2020 09:47:27 -0400 Subject: [PATCH] fix(plugin-kubectl): k get pods --all-namespaces has a title with "default" as the namespace Fixes #4466 --- packages/test/src/api/selectors.ts | 1 + .../src/controller/kubectl/options.ts | 4 +- .../src/lib/view/formatTable.ts | 8 +-- .../src/test/k8s2/get-all-namespaces.ts | 54 ++++++++++++------- .../src/controller/get-pod-data.ts | 4 +- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/packages/test/src/api/selectors.ts b/packages/test/src/api/selectors.ts index cf3cd48e00c..57c5e15b23b 100644 --- a/packages/test/src/api/selectors.ts +++ b/packages/test/src/api/selectors.ts @@ -98,6 +98,7 @@ export const TABLE_SHOW_AS_LIST = (N: number) => `${OUTPUT_N(N)} .kui--toolbar-b export const TABLE_AS_GRID = (N: number) => `${OUTPUT_N(N)} .kui--data-table-as-grid` export const TABLE_AS_LIST = (N: number) => `${OUTPUT_N(N)} .bx--data-table:not(.kui--data-table-as-grid)` export const TABLE_TITLE = (N: number) => `${OUTPUT_N(N)} .kui--data-table-title` +export const TABLE_TITLE_SECONDARY = (N: number) => `${OUTPUT_N(N)} .kui--secondary-breadcrumb` export const BY_NAME = (name: string) => `tbody [data-name="${name}"]` export const LIST_RESULT_FIRST = 'tbody tr:first-child .clickable' export const LIST_RESULT_BY_N_AND_NAME = (N: number, name: string) => diff --git a/plugins/plugin-kubectl/src/controller/kubectl/options.ts b/plugins/plugin-kubectl/src/controller/kubectl/options.ts index e7094cfda6f..5b5482221cf 100644 --- a/plugins/plugin-kubectl/src/controller/kubectl/options.ts +++ b/plugins/plugin-kubectl/src/controller/kubectl/options.ts @@ -187,8 +187,8 @@ export interface KubeOptions extends ParsedOptions { help?: boolean } -export function isForAllNamespaces(args: Arguments) { - return args.parsedOptions.A || args.parsedOptions['all-namespaces'] +export function isForAllNamespaces(parsedOptions: KubeOptions) { + return parsedOptions.A || parsedOptions['all-namespaces'] } export default KubeOptions diff --git a/plugins/plugin-kubectl/src/lib/view/formatTable.ts b/plugins/plugin-kubectl/src/lib/view/formatTable.ts index 238c5c80cf1..7f4499dd5b7 100644 --- a/plugins/plugin-kubectl/src/lib/view/formatTable.ts +++ b/plugins/plugin-kubectl/src/lib/view/formatTable.ts @@ -14,14 +14,16 @@ * limitations under the License. */ -import { Table, Row, Cell, isTable, encodeComponent, Arguments, MixedResponse } from '@kui-shell/core' +import { Table, Row, Cell, isTable, encodeComponent, Arguments, MixedResponse, i18n } from '@kui-shell/core' import TrafficLight from '../model/traffic-light' -import KubeOptions from '../../controller/kubectl/options' +import KubeOptions, { isForAllNamespaces } from '../../controller/kubectl/options' import { RawResponse } from '../../controller/kubectl/response' import cssForValue from './css-for-value' +const strings = i18n('plugin-kubectl') + /** return an array with at least maxColumns entries */ const fillTo = (length: number, maxColumns: number): Cell[] => { if (length >= maxColumns) { @@ -312,7 +314,7 @@ export const formatTable = ( body: rows.slice(1), noSort: true, title: capitalize(entityTypeFromRows || entityTypeFromCommandLine), - breadcrumbs: [{ label: ns || 'default' }] + breadcrumbs: [{ label: ns || (isForAllNamespaces(options) && strings('all')) || 'default' }] } } diff --git a/plugins/plugin-kubectl/src/test/k8s2/get-all-namespaces.ts b/plugins/plugin-kubectl/src/test/k8s2/get-all-namespaces.ts index ccae9ca8e7a..f21ead19e12 100644 --- a/plugins/plugin-kubectl/src/test/k8s2/get-all-namespaces.ts +++ b/plugins/plugin-kubectl/src/test/k8s2/get-all-namespaces.ts @@ -23,6 +23,8 @@ import { waitTillNone } from '@kui-shell/plugin-kubectl/tests/lib/k8s/utils' +import * as assert from 'assert' + const synonyms = ['kubectl'] describe(`kubectl get all-namespaces ${process.env.MOCHA_RUN_TARGET || ''}`, function(this: Common.ISuite) { @@ -55,26 +57,38 @@ describe(`kubectl get all-namespaces ${process.env.MOCHA_RUN_TARGET || ''}`, fun /** list pods across all namespaces, then find the pod corresponding to the given namespace `ns` */ const listAndClickOn = (ns: string) => { - it(`should list pods --all-namespaces expecting ns ${ns} via ${kubectl} then click`, async () => { - try { - const selector = await CLI.command(`${kubectl} get pods --all-namespaces`, this.app).then( - ReplExpect.okWithCustom({ selector: Selectors.BY_NAME(ns) }) - ) - - // wait for the badge to become green - await waitForGreen(this.app, selector) - - // make sure the NAME cell is clickable (as opposed to, say, the NAMESPACE cell) - await this.app.client.waitForExist(`${selector} .clickable[data-key="NAME"]`) - - // now click on that cell - await this.app.client.click(`${selector} .clickable`) - await SidecarExpect.open(this.app) - .then(SidecarExpect.mode(defaultModeForGet)) - .then(SidecarExpect.showing('nginx', undefined, undefined, ns)) - } catch (err) { - return Common.oops(this, true)(err) - } + const allNamespaces = ['--all-namespaces', '-A'] + + allNamespaces.forEach(allNamespace => { + it(`should list pods ${allNamespace} expecting ns ${ns} via ${kubectl} then click`, async () => { + try { + const { app, count } = await CLI.command(`${kubectl} get pods ${allNamespace}`, this.app) + + await this.app.client.waitForExist(Selectors.TABLE_TITLE(count)) + + const actualTitle = await this.app.client.getText(Selectors.TABLE_TITLE(count)) + assert.strictEqual(actualTitle, 'Pod') + + const secondaryTitle = await this.app.client.getText(Selectors.TABLE_TITLE_SECONDARY(count)) + assert.strictEqual(secondaryTitle, 'all') + + const selector = await ReplExpect.okWithCustom({ selector: Selectors.BY_NAME(ns) })({ app, count }) + + // wait for the badge to become green + await waitForGreen(this.app, selector) + + // make sure the NAME cell is clickable (as opposed to, say, the NAMESPACE cell) + await this.app.client.waitForExist(`${selector} .clickable[data-key="NAME"]`) + + // now click on that cell + await this.app.client.click(`${selector} .clickable`) + await SidecarExpect.open(this.app) + .then(SidecarExpect.mode(defaultModeForGet)) + .then(SidecarExpect.showing('nginx', undefined, undefined, ns)) + } catch (err) { + return Common.oops(this, true)(err) + } + }) }) } diff --git a/plugins/plugin-kubectl/view-utilization/src/controller/get-pod-data.ts b/plugins/plugin-kubectl/view-utilization/src/controller/get-pod-data.ts index 6a076ea2e7d..db0e3f7ea3d 100644 --- a/plugins/plugin-kubectl/view-utilization/src/controller/get-pod-data.ts +++ b/plugins/plugin-kubectl/view-utilization/src/controller/get-pod-data.ts @@ -202,7 +202,7 @@ async function getPodDataForAllNodes( args: Arguments, top: (args: Arguments) => Promise ): Promise
{ - if (isForAllNamespaces(args) || args.parsedOptions.containers) { + if (isForAllNamespaces(args.parsedOptions) || args.parsedOptions.containers) { return top(args) } else { const [forThisNS, forAllNS] = await Promise.all([top(args), top(withAllNamespaces(args))]) @@ -224,7 +224,7 @@ async function getPodDataForOneNode( // strip off the --node option strip(args, '--node', 1) // 1 means --node takes 1 arg - if (isForAllNamespaces(args) || args.parsedOptions.containers) { + if (isForAllNamespaces(args.parsedOptions) || args.parsedOptions.containers) { const [podTable, pods] = await Promise.all([top(args), getPodsInNode(args, forNode)]) if (podTable.body) {