Skip to content

Commit

Permalink
fix(plugins/plugin-kubectl): cache kind canonicalization lookup
Browse files Browse the repository at this point in the history
Fixes #4489
  • Loading branch information
starpit committed May 7, 2020
1 parent 8fbdce5 commit cfa78f0
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions plugins/plugin-kubectl/src/controller/kubectl/explain.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 IBM Corporation
* Copyright 2019-2020 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -50,7 +50,7 @@ ${formatDocumentation(_[4])}
}
}

// alternate patterns to match against
/** alternate patterns to match against */
const kvd = /^KIND:\s+(\S+)\nVERSION:\s+(\S+)\n\nDESCRIPTION:\n(\s*DEPRECATED - )?([\s\S]+)/
const kvdf = /^KIND:\s+(\S+)\nVERSION:\s+(\S+)\n\nDESCRIPTION:\n(\s*DEPRECATED - )?([\s\S]+)\n\nFIELDS:\n([\s\S]+)/

Expand Down Expand Up @@ -127,22 +127,38 @@ ${isDeprecated ? `### Warnings\n${strings('This API Resource is deprecated')}` :
return response
}

/**
* Cache of the getKind() lookup
*
*/
const cache: Record<string, Promise<string>> = {}

/**
* @param kindAsProvidedByUser e.g. pod or po
* @return e.g. Pod
*
*/
export async function getKind(command: string, args: Arguments, kindAsProvidedByUser: string): Promise<string> {
try {
const ourArgs = Object.assign({}, args, { command: `kubectl explain ${kindAsProvidedByUser}` })
const explained = await doExecWithStdout(ourArgs, undefined, command)

return explained.match(/^KIND:\s+(.*)/)[1]
} catch (err) {
if (!/does not exist/i.test(err.message)) {
console.error(`error explaining kind ${kindAsProvidedByUser}`, err)
}
if (!cache[kindAsProvidedByUser]) {
// otherwise, we need to do a more expensive call to `kubectl`
// eslint-disable-next-line no-async-promise-executor
cache[kindAsProvidedByUser] = new Promise<string>(async (resolve, reject) => {
try {
const ourArgs = Object.assign({}, args, { command: `${command} explain ${kindAsProvidedByUser}` })
const explained = await doExecWithStdout(ourArgs, undefined, command)

const kindFromServer = explained.match(/^KIND:\s+(.*)/)[1]
resolve(kindFromServer)
} catch (err) {
if (!/does not exist/i.test(err.message)) {
console.error(`error explaining kind ${kindAsProvidedByUser}`, err)
reject(err)
}
}
})
}

return cache[kindAsProvidedByUser]
}

export default (registrar: Registrar) => {
Expand Down

0 comments on commit cfa78f0

Please sign in to comment.