From 6a1f9430e027ebcc0a96ee221958aaf80d8637f6 Mon Sep 17 00:00:00 2001 From: Gajus Kuizinas Date: Tue, 7 May 2019 13:11:21 +0100 Subject: [PATCH] feat: add isKubernetesCredentialsPresent --- README.md | 188 +++++++++--------- package.json | 36 ++-- src/index.js | 3 + src/services/getCredentials.js | 12 +- src/utilities/index.js | 2 + .../isKubernetesCredentialsPresent.js | 21 ++ src/utilities/read.js | 11 + 7 files changed, 155 insertions(+), 118 deletions(-) create mode 100644 src/utilities/isKubernetesCredentialsPresent.js create mode 100644 src/utilities/read.js diff --git a/README.md b/README.md index 4310a97..5201878 100644 --- a/README.md +++ b/README.md @@ -39,87 +39,90 @@ Preoom allows to set up a regular check for memory usage and gracefully shutdown ```js import { - createResourceObserver + createResourceObserver, + isKubernetesCredentialsPresent } from 'preoom'; const main = async () => { const resourceObserver = createResourceObserver(); - console.log(await resourceObserver.getPodResourceSpecification()); - - // { - // containers: [ - // { - // name: 'authentication-proxy', - // resources: { - // limits: { - // cpu: '500m', - // memory: 536870912 - // }, - // requests: { - // cpu: '250m', - // memory: 268435456 - // } - // } - // }, - // { - // name: 'monitoring-proxy', - // resources: { - // limits: { - // cpu: '1', - // memory: 536870912 - // }, - // requests: { - // cpu: '500m', - // memory: 268435456 - // } - // } - // }, - // { - // name: 'showtime-api', - // resources: { - // limits: { - // cpu: '2', - // memory: 2147483648 - // }, - // requests: { - // cpu: '1', - // memory: 1073741824 - // } - // } - // } - // ], - // name: 'showtime-api-56568dd94-tz8df' - // } - - console.log(await resourceObserver.getPodResourceUsage()); - - // { - // containers: [ - // { - // name: 'authentication-proxy', - // usage: { - // cpu: '0', - // memory: 101044224 - // } - // }, - // { - // name: 'monitoring-proxy', - // usage: { - // cpu: '1m', - // memory: 42151936 - // } - // }, - // { - // name: 'showtime-api', - // usage: { - // cpu: '0', - // memory: 1349738496 - // } - // } - // ], - // name: 'showtime-api-56568dd94-tz8df' - // } + if (isKubernetesCredentialsPresent()) { + console.log(await resourceObserver.getPodResourceSpecification()); + + // { + // containers: [ + // { + // name: 'authentication-proxy', + // resources: { + // limits: { + // cpu: '500m', + // memory: 536870912 + // }, + // requests: { + // cpu: '250m', + // memory: 268435456 + // } + // } + // }, + // { + // name: 'monitoring-proxy', + // resources: { + // limits: { + // cpu: '1', + // memory: 536870912 + // }, + // requests: { + // cpu: '500m', + // memory: 268435456 + // } + // } + // }, + // { + // name: 'showtime-api', + // resources: { + // limits: { + // cpu: '2', + // memory: 2147483648 + // }, + // requests: { + // cpu: '1', + // memory: 1073741824 + // } + // } + // } + // ], + // name: 'showtime-api-56568dd94-tz8df' + // } + + console.log(await resourceObserver.getPodResourceUsage()); + + // { + // containers: [ + // { + // name: 'authentication-proxy', + // usage: { + // cpu: '0', + // memory: 101044224 + // } + // }, + // { + // name: 'monitoring-proxy', + // usage: { + // cpu: '1m', + // memory: 42151936 + // } + // }, + // { + // name: 'showtime-api', + // usage: { + // cpu: '0', + // memory: 1349738496 + // } + // } + // ], + // name: 'showtime-api-56568dd94-tz8df' + // } + } }; main(); @@ -135,7 +138,8 @@ import { createLightship } from 'lightship'; import { - createResourceObserver + createResourceObserver, + isKubernetesCredentialsPresent } from 'preoom'; const MAXIMUM_MEMORY_USAGE = 0.95; @@ -143,25 +147,27 @@ const MAXIMUM_MEMORY_USAGE = 0.95; const main = async () => { const lightship = createLightship(); - const resourceObserver = createResourceObserver(); + if (isKubernetesCredentialsPresent()) { + const resourceObserver = createResourceObserver(); - resourceObserver.observe((podResourceSpecification, podResourceUsage) => { - for (const containerResourceSpecification of podResourceSpecification.containers) { - if (containerResourceSpecification.resources.limits && containerResourceSpecification.resources.limits.memory) { - const containerResourceUsage = podResourceUsage.containers.find((container) => { - return container.name === containerResourceSpecification.name; - }); + resourceObserver.observe((podResourceSpecification, podResourceUsage) => { + for (const containerResourceSpecification of podResourceSpecification.containers) { + if (containerResourceSpecification.resources.limits && containerResourceSpecification.resources.limits.memory) { + const containerResourceUsage = podResourceUsage.containers.find((container) => { + return container.name === containerResourceSpecification.name; + }); - if (!containerResourceUsage) { - throw new Error('Unexpected state.'); - } + if (!containerResourceUsage) { + throw new Error('Unexpected state.'); + } - if (containerResourceUsage.usage.memory / containerResourceSpecification.resources.limits.memory > MAXIMUM_MEMORY_USAGE) { - lightship.shutdown(); + if (containerResourceUsage.usage.memory / containerResourceSpecification.resources.limits.memory > MAXIMUM_MEMORY_USAGE) { + lightship.shutdown(); + } } } - } - }, 5 * 1000); + }, 5 * 1000); + } lightship.signalReady(); } diff --git a/package.json b/package.json index 56e5d7f..0bc1791 100644 --- a/package.json +++ b/package.json @@ -10,28 +10,28 @@ ] }, "dependencies": { - "bytes-iec": "^3.0.1", - "got": "^9.5.0", - "roarr": "^2.12.1" + "bytes-iec": "^3.1.0", + "got": "^9.6.0", + "roarr": "^2.13.0" }, "description": "Retrieves & observes Kubernetes Pod resource (CPU, memory) utilisation.", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", + "@babel/cli": "^7.4.4", + "@babel/core": "^7.4.4", "@babel/node": "^7.2.2", - "@babel/plugin-transform-flow-strip-types": "^7.2.3", - "@babel/preset-env": "^7.2.3", - "@babel/register": "^7.0.0", - "ava": "^1.0.1", - "babel-plugin-istanbul": "^5.1.0", - "coveralls": "^3.0.2", - "delay": "^4.1.0", - "eslint": "^5.11.1", - "eslint-config-canonical": "^15.1.1", - "flow-bin": "^0.89.0", - "flow-copy-source": "^2.0.2", - "nyc": "^13.1.0", - "semantic-release": "^15.13.2" + "@babel/plugin-transform-flow-strip-types": "^7.4.4", + "@babel/preset-env": "^7.4.4", + "@babel/register": "^7.4.4", + "ava": "^1.4.1", + "babel-plugin-istanbul": "^5.1.4", + "coveralls": "^3.0.3", + "delay": "^4.2.0", + "eslint": "^5.16.0", + "eslint-config-canonical": "^17.0.1", + "flow-bin": "^0.98.1", + "flow-copy-source": "^2.0.4", + "nyc": "^14.1.0", + "semantic-release": "^15.13.3" }, "engines": { "node": ">6" diff --git a/src/index.js b/src/index.js index e49e6f9..d52c324 100644 --- a/src/index.js +++ b/src/index.js @@ -3,3 +3,6 @@ export { createResourceObserver } from './factories'; +export { + isKubernetesCredentialsPresent +} from './utilities'; diff --git a/src/services/getCredentials.js b/src/services/getCredentials.js index 4abd993..1144416 100644 --- a/src/services/getCredentials.js +++ b/src/services/getCredentials.js @@ -2,7 +2,9 @@ /* eslint-disable no-process-env */ -import fs from 'fs'; +import { + read +} from '../utilities'; type CredentialsType = {| +podName: string, @@ -12,14 +14,6 @@ type CredentialsType = {| +serviceUrl: string |}; -const read = (filePath: string): string | null => { - try { - return fs.readFileSync(filePath, 'utf8'); - } catch (error) { - return null; - } -}; - export default (): CredentialsType => { const kubernetesServiceHost = process.env.KUBERNETES_SERVICE_HOST || null; const kubernetesServicePort = process.env.KUBERNETES_PORT_443_TCP_PORT || null; diff --git a/src/utilities/index.js b/src/utilities/index.js index c382082..7736dc5 100644 --- a/src/utilities/index.js +++ b/src/utilities/index.js @@ -1,3 +1,5 @@ // @flow +export {default as isKubernetesCredentialsPresent} from './isKubernetesCredentialsPresent'; export {default as parseBytes} from './parseBytes'; +export {default as read} from './read'; diff --git a/src/utilities/isKubernetesCredentialsPresent.js b/src/utilities/isKubernetesCredentialsPresent.js new file mode 100644 index 0000000..d8ca2f8 --- /dev/null +++ b/src/utilities/isKubernetesCredentialsPresent.js @@ -0,0 +1,21 @@ +// @flow + +/* eslint-disable no-process-env */ + +import read from './read'; + +export default () => { + const kubernetesServiceHost = process.env.KUBERNETES_SERVICE_HOST || null; + const kubernetesServicePort = process.env.KUBERNETES_PORT_443_TCP_PORT || null; + const podName = process.env.HOSTNAME || null; + + if (!kubernetesServiceHost || !kubernetesServicePort || !podName) { + return false; + } + + const serviceAccountToken = read('/var/run/secrets/kubernetes.io/serviceaccount/token'); + const serviceCertificateAuthority = read('/var/run/secrets/kubernetes.io/serviceaccount/ca.crt'); + const podNamespace = read('/var/run/secrets/kubernetes.io/serviceaccount/namespace'); + + return serviceAccountToken && serviceCertificateAuthority && podNamespace; +}; diff --git a/src/utilities/read.js b/src/utilities/read.js new file mode 100644 index 0000000..c645d42 --- /dev/null +++ b/src/utilities/read.js @@ -0,0 +1,11 @@ +// @flow + +import fs from 'fs'; + +export default (filePath: string): string | null => { + try { + return fs.readFileSync(filePath, 'utf8'); + } catch (error) { + return null; + } +};