Skip to content

Commit

Permalink
feat: improve Pod->PVC->PV drilldowns
Browse files Browse the repository at this point in the history
  • Loading branch information
starpit committed Feb 9, 2023
1 parent 34378be commit 821b23d
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 0 deletions.
4 changes: 4 additions & 0 deletions plugins/plugin-kubectl-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export {
KubePartial,
PodList,
isPodList,
isPVCVolume,
KubeContext,
CustomResourceDefinition,
isCustomResourceDefinition,
Expand Down Expand Up @@ -78,6 +79,9 @@ export {
isMetaTable,
MetaTable,
KubeContainerStatus,
PVC,
isPVC,
isBoundPVC,
Status,
isStatus
} from './resource'
Expand Down
24 changes: 24 additions & 0 deletions plugins/plugin-kubectl-core/src/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ export interface PodStatus extends KubeStatus {
export interface PodLikeSpec {
_podName: string // allows pod-like resources to define the actual pod name
}
type PVCVolume = {
persistentVolumeClaim: { claimName: string }
}
type Volume = PVCVolume // or others?
export function isPVCVolume(volume: Volume): volume is PVCVolume {
return typeof volume.persistentVolumeClaim === 'object' && typeof volume.persistentVolumeClaim.claimName === 'string'
}
export interface Pod extends KubeResource<PodStatus> {
apiVersion: 'v1'
kind: 'Pod'
Expand All @@ -332,6 +339,7 @@ export interface Pod extends KubeResource<PodStatus> {
nominatedNodeName?: string
readinessGates?: { conditionType: string }[]
containers: ContainerSpec[]
volumes?: Volume[]
}
}

Expand Down Expand Up @@ -787,3 +795,19 @@ export function hasAnnotations(resource: KubeResource): resource is KubeResource
export function hasLabels(resource: KubeResource): resource is KubeResource {
return isKubeResource(resource) && resource.metadata.labels && Object.keys(resource.metadata.labels).length > 0
}

/** PersistentVolumeClaim */
export interface PVC extends KubeResource {
kind: 'PersistentVolumeClaim'
spec: {
volumeName: string
volumeMode: string
storageClassName: string
}
}
export function isPVC(resource: KubeResource): resource is PVC {
return resource.apiVersion === 'v1' && resource.kind === 'PersistentVolumeClaim'
}
export function isBoundPVC(resource: KubeResource): resource is PVC {
return isPVC(resource) && typeof resource.spec.volumeName === 'string'
}
53 changes: 53 additions & 0 deletions plugins/plugin-kubectl/src/lib/view/modes/ShowBoundVolumeButton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2023 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { PVC, isBoundPVC } from '@kui-shell/plugin-kubectl-core'
import { Arguments, i18n, Tab, ModeRegistration } from '@kui-shell/core'

import { withKubeconfigFrom } from '../../../controller/kubectl/options'

const strings = i18n('plugin-kubectl')

/**
* Show the bound Persistent Volume associated with a PersistentVolumeClaim
*
*/
async function command(
tab: Tab,
{ spec: { volumeName } }: PVC,
args: Pick<Arguments, 'argvNoOptions' | 'parsedOptions'>
) {
const { getCommandFromArgs } = await import('../../util/util')

return withKubeconfigFrom(args, `${getCommandFromArgs(args)} get pv ${volumeName} -o yaml`)
}

/**
* Add an Involved Object mode button
*
*/
const mode: ModeRegistration<PVC> = {
when: isBoundPVC,
mode: {
mode: 'boundPVC',
kind: 'drilldown',
showRelatedResource: true,
label: strings('Show Bound Volume'),
command
}
}

export default mode
59 changes: 59 additions & 0 deletions plugins/plugin-kubectl/src/lib/view/modes/ShowPVCsButton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2023 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Arguments, i18n, Tab, ModeRegistration } from '@kui-shell/core'
import { KubeResource, Pod, isPod, isPVCVolume } from '@kui-shell/plugin-kubectl-core'

import { withKubeconfigFrom } from '../../../controller/kubectl/options'

const strings = i18n('plugin-kubectl')

/**
* Show the PersistentVolumeClaim associated with a Pod
*
*/
async function command(tab: Tab, pod: Pod, args: Pick<Arguments, 'argvNoOptions' | 'parsedOptions'>) {
const { getCommandFromArgs } = await import('../../util/util')

const pvcVolumes = pod.spec.volumes.filter(isPVCVolume)
const dashO = pvcVolumes.length === 1 ? '-o yaml' : '' // skip directly to drilldown if there's just one

return withKubeconfigFrom(
args,
`${getCommandFromArgs(args)} get pvc ${pvcVolumes.map(_ => _.persistentVolumeClaim.claimName).join(' ')} ${dashO}`
)
}

function hasPVCs(resource: KubeResource): resource is Pod {
return isPod(resource) && Array.isArray(resource.spec.volumes) && !!resource.spec.volumes.find(isPVCVolume)
}

/**
* Add an Involved Object mode button
*
*/
const mode: ModeRegistration<Pod> = {
when: hasPVCs,
mode: {
mode: 'associatedPVCs',
kind: 'drilldown',
showRelatedResource: true,
label: strings('Show Volume Claims'),
command
}
}

export default mode
4 changes: 4 additions & 0 deletions plugins/plugin-kubectl/src/non-headless-preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import containersMode from './lib/view/modes/Containers'
import logsMode from './lib/view/modes/logs-mode'
import ExecIntoPad from './lib/view/modes/ExecIntoPod'
import lastAppliedMode from './lib/view/modes/last-applied'
import showPVCsButton from './lib/view/modes/ShowPVCsButton'
import showBoundVolumeButton from './lib/view/modes/ShowBoundVolumeButton'
import showOwnerButton from './lib/view/modes/ShowOwnerButton'
import showNodeButton from './lib/view/modes/ShowNodeOfPodButton'
import deleteResourceButton from './lib/view/modes/DeleteButton'
Expand Down Expand Up @@ -63,6 +65,8 @@ export default async (registrar: PreloadRegistrar) => {
EditButton,
// managedFieldsMode,
showCRDResources,
showPVCsButton,
showBoundVolumeButton,
showOwnerButton,
showNodeButton,
deleteResourceButton,
Expand Down

0 comments on commit 821b23d

Please sign in to comment.