From d222721079fa660116a144bcd761d340e8017fb0 Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Tue, 5 Jun 2018 18:54:44 +0200 Subject: [PATCH 1/6] fix: malformed output from `ctx.getStatus()` (#134) --- src/plugin-context.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugin-context.ts b/src/plugin-context.ts index 2433517daf..ea9af63bf1 100644 --- a/src/plugin-context.ts +++ b/src/plugin-context.ts @@ -486,15 +486,15 @@ export function createPluginContext(garden: Garden): PluginContext { getStatus: async () => { const envStatus: EnvironmentStatusMap = await ctx.getEnvironmentStatus({}) - const services = await ctx.getServices() + const services = keyBy(await ctx.getServices(), "name") - const serviceStatus = await Bluebird.map( - services, (service: Service) => ctx.getServiceStatus({ serviceName: service.name }), - ) + const serviceStatus = await Bluebird.props(mapValues(services, + (service: Service) => ctx.getServiceStatus({ serviceName: service.name }), + )) return { providers: envStatus, - services: keyBy(serviceStatus, "name"), + services: serviceStatus, } }, From 41f1482850db8fc7b3733c0476ade5d055c2fd3c Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Wed, 6 Jun 2018 22:49:03 +0200 Subject: [PATCH 2/6] fix(k8s): better error message when kubectl fails --- src/plugins/kubernetes/kubectl.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/kubernetes/kubectl.ts b/src/plugins/kubernetes/kubectl.ts index ba3d807f5a..b6d50050d2 100644 --- a/src/plugins/kubernetes/kubectl.ts +++ b/src/plugins/kubernetes/kubectl.ts @@ -87,7 +87,11 @@ export class Kubectl { const _reject = (msg: string) => { const dataStr = data ? data.toString() : null const details = extend({ args, preparedArgs, msg, data: dataStr }, out) - const err = new RuntimeError(`Failed running 'kubectl ${args.join(" ")}'`, details) + + const err = new RuntimeError( + `Failed running 'kubectl ${preparedArgs.join(" ")}': ${out.output}`, + details, + ) reject(err) } From b0eb86e74044b476edf6b914ce24ceabe20e5f62 Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Wed, 6 Jun 2018 22:49:45 +0200 Subject: [PATCH 3/6] fix(ctx): better error.log output from `processModules()` --- src/process.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/process.ts b/src/process.ts index d69627b575..5293adfed5 100644 --- a/src/process.ts +++ b/src/process.ts @@ -21,6 +21,7 @@ import { import { padEnd, values, flatten } from "lodash" import { getNames, registerCleanupFunction } from "./util/util" import { PluginContext } from "./plugin-context" +import { toGardenError } from "./exceptions" export type ProcessModule = (module: Module) => Promise export type ProcessService = (service: Service) => Promise @@ -52,11 +53,10 @@ export async function processModules({ pluginContext, modules, watch, process }: const logErrors = (taskResults: TaskResults) => { for (const result of values(taskResults).filter(r => !!r.error)) { const divider = padEnd("", 80, "—") + const error = toGardenError(result.error!) + const msg = `\nFailed ${result.description}. Here is the output:\n${divider}\n${error.message}\n${divider}\n` - ctx.log.error(`\nFailed ${result.description}. Here is the output:`) - ctx.log.error(divider) - ctx.log.error(result.error + "") - ctx.log.error(divider + "\n") + ctx.log.error({ msg, error }) } } From f674d2ad6a67bc906fa27ba12508488e8ce5108f Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Wed, 13 Jun 2018 22:09:23 +0200 Subject: [PATCH 4/6] chore: update nginx ingress controller --- static/kubernetes/system/ingress-controller/garden.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/kubernetes/system/ingress-controller/garden.yml b/static/kubernetes/system/ingress-controller/garden.yml index 1873c16d33..8beb725ae8 100644 --- a/static/kubernetes/system/ingress-controller/garden.yml +++ b/static/kubernetes/system/ingress-controller/garden.yml @@ -2,7 +2,7 @@ module: description: Ingress controller for garden development name: k8s-ingress-controller type: container - image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0-beta.19 + image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0 services: - name: ingress-controller command: From 8ccd9a1a7e74bcc95cfc49a6af9812ec84281a52 Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Wed, 13 Jun 2018 22:06:18 +0200 Subject: [PATCH 5/6] refactor: switch to official kubernetes client library --- package-lock.json | 1414 +++++++++++++++------------ package.json | 4 +- src/plugins/kubernetes/actions.ts | 102 +- src/plugins/kubernetes/api.ts | 83 +- src/plugins/kubernetes/namespace.ts | 21 +- src/plugins/kubernetes/status.ts | 14 +- src/util/util.ts | 6 +- 7 files changed, 948 insertions(+), 696 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7beb78eabb..9866aecd6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -394,6 +394,36 @@ "through2": "^2.0.3" } }, + "@kubernetes/client-node": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.3.0.tgz", + "integrity": "sha512-0gdIKJV4izFMOOEHipE/AfdI+nd2KftE1kiQCEToumu0VsnXV14A/1/LMxkkJqsqMKrgyp92k/Kz5gmyetvRcw==", + "requires": { + "@types/base-64": "^0.1.2", + "@types/bluebird": "^3.5.7", + "@types/js-yaml": "^3.5.31", + "@types/node": "^8.0.2", + "@types/request": "^2.47.0", + "@types/underscore": "^1.8.1", + "@types/websocket": "0.0.38", + "base-64": "^0.1.0", + "bluebird": "^3.3.5", + "byline": "^5.0.0", + "js-yaml": "^3.5.2", + "jsonpath": "^0.2.11", + "request": "^2.72.0", + "shelljs": "^0.7.8 ", + "underscore": "^1.8.3", + "websocket": "^1.0.25" + }, + "dependencies": { + "@types/node": { + "version": "8.10.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.20.tgz", + "integrity": "sha512-M7x8+5D1k/CuA6jhiwuSCmE8sbUWJF0wYsjcig9WrXvwUI5ArEoUBdOXpV4JcEMrLp02/QbDjw+kI+vQeKyQgg==" + } + } + }, "@lerna/add": { "version": "3.0.0-beta.21", "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.0.0-beta.21.tgz", @@ -2409,16 +2439,20 @@ "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", "dev": true }, - "@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==" + "@types/base-64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/base-64/-/base-64-0.1.2.tgz", + "integrity": "sha1-Y6wxgwLNq7XwToripW5U1IMhB+I=" }, "@types/bluebird": { "version": "3.5.20", "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.20.tgz", - "integrity": "sha512-Wk41MVdF+cHBfVXj/ufUHJeO3BlIQr1McbHZANErMykaCWeDSZbH5erGjNBw2/3UlRdSxZbLfSuQTzFmPOYFsA==", - "dev": true + "integrity": "sha512-Wk41MVdF+cHBfVXj/ufUHJeO3BlIQr1McbHZANErMykaCWeDSZbH5erGjNBw2/3UlRdSxZbLfSuQTzFmPOYFsA==" + }, + "@types/caseless": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz", + "integrity": "sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A==" }, "@types/chai": { "version": "4.1.3", @@ -2470,8 +2504,16 @@ "@types/events": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + }, + "@types/execa": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/execa/-/execa-0.9.0.tgz", + "integrity": "sha512-mgfd93RhzjYBUHHV532turHC2j4l/qxsF/PbfDmprHDEUHmNZGlDn1CEsulGK3AfsPdhkWzZQT/S/k0UGhLGsA==", + "dev": true, + "requires": { + "@types/node": "*" + } }, "@types/fancy-log": { "version": "1.3.0", @@ -2479,6 +2521,14 @@ "integrity": "sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw==", "dev": true }, + "@types/form-data": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", + "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "requires": { + "@types/node": "*" + } + }, "@types/fs-extra": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.3.tgz", @@ -2551,8 +2601,7 @@ "@types/js-yaml": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.11.1.tgz", - "integrity": "sha512-M5qhhfuTt4fwHGqqANNQilp3Htb5cHwBxlMHDUw/TYRVkEp3s3IIFSH3Fe9HIAeEtnO4p3SSowLmCVavdRYfpw==", - "dev": true + "integrity": "sha512-M5qhhfuTt4fwHGqqANNQilp3Htb5cHwBxlMHDUw/TYRVkEp3s3IIFSH3Fe9HIAeEtnO4p3SSowLmCVavdRYfpw==" }, "@types/json-schema": { "version": "4.0.0", @@ -2658,6 +2707,17 @@ "integrity": "sha1-ExqJDe1kIbG1RfRRCkrqvG1GUnU=", "dev": true }, + "@types/request": { + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.0.tgz", + "integrity": "sha512-/KXM5oev+nNCLIgBjkwbk8VqxmzI56woD4VUxn95O+YeQ8hJzcSmIZ1IN3WexiqBb6srzDo2bdMbsXxgXNkz5Q==", + "requires": { + "@types/caseless": "*", + "@types/form-data": "*", + "@types/node": "*", + "@types/tough-cookie": "*" + } + }, "@types/rx": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz", @@ -2799,6 +2859,16 @@ "@types/node": "*" } }, + "@types/tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha512-MDQLxNFRLasqS4UlkWMSACMKeSm1x4Q3TxzUC7KQUsh6RK1ZrQ0VEyE3yzXcBu+K8ejVj4wuX32eUG02yNp+YQ==" + }, + "@types/underscore": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.8.tgz", + "integrity": "sha512-EquzRwzAAs04anQ8/6MYXFKvHoD+MIlF+gu87EDda7dN9zrKvQYHsc9VFAPB1xY4tUHQVvBMtjsHrvof2EE1Mg==" + }, "@types/undertaker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.0.tgz", @@ -2841,12 +2911,26 @@ "@types/vinyl": "*" } }, + "@types/websocket": { + "version": "0.0.38", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-0.0.38.tgz", + "integrity": "sha512-Z7dRTAiMoIjz9HBa/xb3k+2mx2uJx2sbnbkRRIvM+l/srNLfthHFBW/jD59thOcEa1/ZooKd30G0D+KGH9wU7Q==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, "@types/wrap-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", "dev": true }, + "JSONSelect": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", + "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=" + }, "JSONStream": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", @@ -3436,10 +3520,10 @@ } } }, - "base64url": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.0.tgz", - "integrity": "sha512-LIVmqIrIWuiqTvn4RzcrwCOuHo2DD6tKmKBPXXlr4p4n4l6BZBkwFTIa3zu1XkX5MbZgro4a6BvPi+n2Mns5Gg==" + "base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=" }, "bcrypt-pbkdf": { "version": "1.0.1", @@ -3621,8 +3705,7 @@ "byline": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", - "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", - "dev": true + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=" }, "bytes": { "version": "3.0.0", @@ -3646,27 +3729,6 @@ "unset-value": "^1.0.0" } }, - "cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", - "requires": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - }, - "dependencies": { - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" - } - } - }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -3835,6 +3897,11 @@ "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", "dev": true }, + "cjson": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.2.1.tgz", + "integrity": "sha1-c82KrWXZ4VBfmvF0TTt5wVJ2gqU=" + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -4052,14 +4119,6 @@ "shallow-clone": "^0.1.2" } }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", @@ -4924,15 +4983,8 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true }, "dedent": { "version": "0.7.0", @@ -5309,7 +5361,8 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true }, "duplexify": { "version": "3.5.4", @@ -5333,6 +5386,11 @@ "object.defaults": "^1.1.0" } }, + "ebnf-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz", + "integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE=" + }, "ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", @@ -5560,7 +5618,6 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^3.0.0", @@ -5575,7 +5632,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -5587,8 +5643,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" } } }, @@ -5984,15 +6039,6 @@ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", @@ -6016,8 +6062,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.2", @@ -7072,7 +7117,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7187,30 +7231,6 @@ "sparkles": "^1.0.0" } }, - "got": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.1.tgz", - "integrity": "sha512-tiLX+bnYm5A56T5N/n9Xo89vMaO1mrS9qoDqj3u/anVooqGozvY/HbXzEpDfbNeKsHCBpK40gSbz8wGYSp3i1w==", - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - } - }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -7791,25 +7811,12 @@ "sparkles": "^1.0.0" } }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -7913,11 +7920,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" - }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -8082,7 +8084,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -8176,17 +8177,7 @@ "interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", - "requires": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - } + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" }, "invariant": { "version": "2.2.4", @@ -8361,11 +8352,6 @@ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" - }, "is-odd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", @@ -8386,7 +8372,8 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true }, "is-plain-object": { "version": "2.0.4", @@ -8425,7 +8412,8 @@ "is-retry-allowed": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true }, "is-stream": { "version": "1.1.0", @@ -8540,13 +8528,50 @@ } } }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "jison": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz", + "integrity": "sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=", "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" + "JSONSelect": "0.4.0", + "cjson": "~0.2.1", + "ebnf-parser": "~0.1.9", + "escodegen": "0.0.21", + "esprima": "1.0.x", + "jison-lex": "0.2.x", + "lex-parser": "~0.1.3", + "nomnom": "1.5.2" + }, + "dependencies": { + "escodegen": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.21.tgz", + "integrity": "sha1-U9ZSz6EDA4gnlFilJmxf/HCcY8M=", + "requires": { + "esprima": "~1.0.2", + "estraverse": "~0.0.4", + "source-map": ">= 0.1.2" + } + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=" + }, + "estraverse": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-0.0.4.tgz", + "integrity": "sha1-AaCTLf7ldGhKWYr1pnw7+bZCjbI=" + } + } + }, + "jison-lex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.2.1.tgz", + "integrity": "sha1-rEuBXozOUTLrErXfz+jXB7iETf4=", + "requires": { + "lex-parser": "0.1.x", + "nomnom": "1.5.2" } }, "joi": { @@ -8586,11 +8611,6 @@ "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", "dev": true }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -8700,6 +8720,29 @@ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" }, + "jsonpath": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-0.2.12.tgz", + "integrity": "sha1-W/nZEftGFsHjNwvs658NskrjTNI=", + "requires": { + "esprima": "1.2.2", + "jison": "0.4.13", + "static-eval": "0.2.3", + "underscore": "1.7.0" + }, + "dependencies": { + "esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs=" + }, + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" + } + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -8717,14 +8760,6 @@ "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", "dev": true }, - "keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", - "requires": { - "json-buffer": "3.0.0" - } - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -8741,19 +8776,6 @@ "graceful-fs": "^4.1.9" } }, - "kubernetes-client": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/kubernetes-client/-/kubernetes-client-5.3.0.tgz", - "integrity": "sha512-i+sg7sk7iRVONnbmZLmUDtE82pc5CWjakMdKrf2h3JbPWjkLIhFJruLHJub8SGLLqDCYuC8KJOai6V5klsGJMA==", - "requires": { - "async": "^2.6.0", - "js-yaml": "^3.10.0", - "lodash.merge": "^4.6.0", - "openid-client": "^2.0.0", - "promy": "^0.1.0", - "request": "^2.83.0" - } - }, "kuler": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-0.0.0.tgz", @@ -8862,6 +8884,11 @@ "type-check": "~0.3.2" } }, + "lex-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz", + "integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA=" + }, "license-checker": { "version": "20.1.0", "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-20.1.0.tgz", @@ -9067,11 +9094,6 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -9092,11 +9114,6 @@ "lodash._root": "^3.0.0" } }, - "lodash.fill": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/lodash.fill/-/lodash.fill-3.4.0.tgz", - "integrity": "sha1-o8dK5kDQU63w3CB5+HIHiOi/74U=" - }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", @@ -9107,11 +9124,6 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, - "lodash.intersection": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.intersection/-/lodash.intersection-4.4.0.tgz", - "integrity": "sha1-ChG6Yx0OlcI8fy9Mu5ppLtF45wU=" - }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -9144,7 +9156,8 @@ "lodash.merge": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "dev": true }, "lodash.mergewith": { "version": "4.6.1", @@ -9155,7 +9168,8 @@ "lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=" + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "dev": true }, "lodash.pad": { "version": "4.5.1", @@ -9175,15 +9189,11 @@ "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", "dev": true }, - "lodash.partialright": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.partialright/-/lodash.partialright-4.2.1.tgz", - "integrity": "sha1-ATDYDoM2MmTUAHTzKbij56ihzEs=" - }, "lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true }, "lodash.restparam": { "version": "3.6.1", @@ -9233,11 +9243,6 @@ "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=", "dev": true }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" - }, "lodash.upperfirst": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", @@ -9271,11 +9276,6 @@ } } }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -9304,7 +9304,8 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true }, "lru-cache": { "version": "4.1.1", @@ -9562,11 +9563,6 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, - "mimic-response": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=" - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -9859,8 +9855,7 @@ "nice-try": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", - "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", - "dev": true + "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==" }, "nock": { "version": "9.3.3", @@ -9917,11 +9912,6 @@ } } }, - "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" - }, "node-gyp": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz", @@ -10057,28 +10047,6 @@ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, - "node-jose": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-1.0.0.tgz", - "integrity": "sha512-RE3P8l60Rj9ELrpPmvw6sOQ1hSyYfmQdNUMCa4EN7nCE1ux5JVX+GfXv+mfUTEMhZwNMwxBtI0+X1CKKeukSVQ==", - "requires": { - "base64url": "^3.0.0", - "es6-promise": "^4.0.5", - "lodash.assign": "^4.0.8", - "lodash.clone": "^4.3.2", - "lodash.fill": "^3.2.2", - "lodash.flatten": "^4.2.0", - "lodash.intersection": "^4.1.2", - "lodash.merge": "^4.3.5", - "lodash.omit": "^4.2.1", - "lodash.partialright": "^4.1.3", - "lodash.pick": "^4.2.0", - "lodash.uniq": "^4.2.1", - "long": "^4.0.0", - "node-forge": "^0.7.1", - "uuid": "^3.0.1" - } - }, "node-pty": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.7.4.tgz", @@ -10117,6 +10085,27 @@ } } }, + "nomnom": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", + "requires": { + "colors": "0.5.x", + "underscore": "1.1.x" + }, + "dependencies": { + "colors": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz", + "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=" + }, + "underscore": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=" + } + } + }, "nopt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.1.tgz", @@ -10147,16 +10136,6 @@ "remove-trailing-separator": "^1.0.1" } }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } - }, "now-and-later": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", @@ -10269,7 +10248,8 @@ "dependencies": { "align-text": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { "kind-of": "^3.0.2", @@ -10279,17 +10259,20 @@ }, "amdefine": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi-regex": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "append-transform": { "version": "0.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", "dev": true, "requires": { "default-require-extensions": "^1.0.0" @@ -10297,57 +10280,68 @@ }, "archy": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "arr-diff": { "version": "4.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "arr-flatten": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-union": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, "array-unique": { "version": "0.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arrify": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "assign-symbols": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "async": { "version": "1.5.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "atob": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", "dev": true }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "base": { "version": "0.11.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { "cache-base": "^1.0.1", @@ -10361,7 +10355,8 @@ "dependencies": { "define-property": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -10369,7 +10364,8 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -10377,7 +10373,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -10385,7 +10382,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -10395,14 +10393,16 @@ }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "brace-expansion": { "version": "1.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -10411,7 +10411,8 @@ }, "braces": { "version": "2.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -10428,7 +10429,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -10438,12 +10440,14 @@ }, "builtin-modules": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, "cache-base": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { "collection-visit": "^1.0.0", @@ -10459,7 +10463,8 @@ }, "caching-transform": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", "dev": true, "requires": { "md5-hex": "^1.2.0", @@ -10469,13 +10474,15 @@ }, "camelcase": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true, "optional": true }, "center-align": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "optional": true, "requires": { @@ -10485,7 +10492,8 @@ }, "class-utils": { "version": "0.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -10496,7 +10504,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -10506,7 +10515,8 @@ }, "cliui": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "optional": true, "requires": { @@ -10517,7 +10527,8 @@ "dependencies": { "wordwrap": { "version": "0.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true, "optional": true } @@ -10525,12 +10536,14 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "collection-visit": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { "map-visit": "^1.0.0", @@ -10539,32 +10552,38 @@ }, "commondir": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "component-emitter": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "convert-source-map": { "version": "1.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, "copy-descriptor": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, "cross-spawn": { "version": "4.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -10573,7 +10592,8 @@ }, "debug": { "version": "3.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -10581,22 +10601,26 @@ }, "debug-log": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", "dev": true }, "decamelize": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decode-uri-component": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "default-require-extensions": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", "dev": true, "requires": { "strip-bom": "^2.0.0" @@ -10604,7 +10628,8 @@ }, "define-property": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { "is-descriptor": "^1.0.2", @@ -10613,7 +10638,8 @@ "dependencies": { "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -10621,7 +10647,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -10629,7 +10656,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -10639,14 +10667,16 @@ }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "error-ex": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -10654,7 +10684,8 @@ }, "execa": { "version": "0.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { "cross-spawn": "^5.0.1", @@ -10668,7 +10699,8 @@ "dependencies": { "cross-spawn": { "version": "5.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -10680,7 +10712,8 @@ }, "expand-brackets": { "version": "2.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { "debug": "^2.3.3", @@ -10694,7 +10727,8 @@ "dependencies": { "debug": { "version": "2.6.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -10702,7 +10736,8 @@ }, "define-property": { "version": "0.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -10710,7 +10745,8 @@ }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -10720,7 +10756,8 @@ }, "extend-shallow": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { "assign-symbols": "^1.0.0", @@ -10729,7 +10766,8 @@ "dependencies": { "is-extendable": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -10739,7 +10777,8 @@ }, "extglob": { "version": "2.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { "array-unique": "^0.3.2", @@ -10754,7 +10793,8 @@ "dependencies": { "define-property": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -10762,7 +10802,8 @@ }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -10770,7 +10811,8 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -10778,7 +10820,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -10786,7 +10829,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -10796,14 +10840,16 @@ }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "fill-range": { "version": "4.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -10814,7 +10860,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -10824,7 +10871,8 @@ }, "find-cache-dir": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", "dev": true, "requires": { "commondir": "^1.0.1", @@ -10834,7 +10882,8 @@ }, "find-up": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -10842,12 +10891,14 @@ }, "for-in": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "foreground-child": { "version": "1.5.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", @@ -10856,7 +10907,8 @@ }, "fragment-cache": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { "map-cache": "^0.2.2" @@ -10864,27 +10916,32 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "get-caller-file": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, "get-stream": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, "get-value": { "version": "2.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, "glob": { "version": "7.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -10897,12 +10954,14 @@ }, "graceful-fs": { "version": "4.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "handlebars": { "version": "4.0.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { "async": "^1.4.0", @@ -10913,7 +10972,8 @@ "dependencies": { "source-map": { "version": "0.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { "amdefine": ">=0.0.4" @@ -10923,7 +10983,8 @@ }, "has-value": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { "get-value": "^2.0.6", @@ -10933,7 +10994,8 @@ }, "has-values": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -10942,7 +11004,8 @@ "dependencies": { "kind-of": { "version": "4.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -10952,17 +11015,20 @@ }, "hosted-git-info": { "version": "2.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, "imurmurhash": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", @@ -10971,17 +11037,20 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "invert-kv": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "is-accessor-descriptor": { "version": "0.1.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -10989,17 +11058,20 @@ }, "is-arrayish": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-buffer": { "version": "1.1.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-builtin-module": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { "builtin-modules": "^1.0.0" @@ -11007,7 +11079,8 @@ }, "is-data-descriptor": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11015,7 +11088,8 @@ }, "is-descriptor": { "version": "0.1.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", @@ -11025,24 +11099,28 @@ "dependencies": { "kind-of": { "version": "5.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } }, "is-extendable": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-number": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11050,7 +11128,8 @@ }, "is-odd": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "dev": true, "requires": { "is-number": "^4.0.0" @@ -11058,14 +11137,16 @@ "dependencies": { "is-number": { "version": "4.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true } } }, "is-plain-object": { "version": "2.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -11073,42 +11154,50 @@ }, "is-stream": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-utf8": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-windows": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isobject": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "istanbul-lib-coverage": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", "dev": true }, "istanbul-lib-hook": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", "dev": true, "requires": { "append-transform": "^0.4.0" @@ -11116,7 +11205,8 @@ }, "istanbul-lib-report": { "version": "1.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-D4jVbMDtT2dPmloPJS/rmeP626N5Pr3Rp+SovrPn1+zPChGHcggd/0sL29jnbm4oK9W0wHjCRsdch9oLd7cm6g==", "dev": true, "requires": { "istanbul-lib-coverage": "^1.1.2", @@ -11127,12 +11217,14 @@ "dependencies": { "has-flag": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "supports-color": { "version": "3.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { "has-flag": "^1.0.0" @@ -11142,7 +11234,8 @@ }, "istanbul-lib-source-maps": { "version": "1.2.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz", + "integrity": "sha1-/+a+Tnq4bTYD5CkNVJkLFFBvybE=", "dev": true, "requires": { "debug": "^3.1.0", @@ -11154,7 +11247,8 @@ }, "istanbul-reports": { "version": "1.4.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.4.1.tgz", + "integrity": "sha1-Ty6OkoqnoF0dpsQn1AmLJlXsczQ=", "dev": true, "requires": { "handlebars": "^4.0.3" @@ -11162,7 +11256,8 @@ }, "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11170,13 +11265,15 @@ }, "lazy-cache": { "version": "1.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true, "optional": true }, "lcid": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" @@ -11184,7 +11281,8 @@ }, "load-json-file": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -11196,7 +11294,8 @@ }, "locate-path": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -11205,19 +11304,22 @@ "dependencies": { "path-exists": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "longest": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, "lru-cache": { "version": "4.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -11226,12 +11328,14 @@ }, "map-cache": { "version": "0.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-visit": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { "object-visit": "^1.0.0" @@ -11239,7 +11343,8 @@ }, "md5-hex": { "version": "1.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", "dev": true, "requires": { "md5-o-matic": "^0.1.1" @@ -11247,12 +11352,14 @@ }, "md5-o-matic": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", "dev": true }, "mem": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { "mimic-fn": "^1.0.0" @@ -11260,7 +11367,8 @@ }, "merge-source-map": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" @@ -11268,14 +11376,16 @@ "dependencies": { "source-map": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "micromatch": { "version": "3.1.10", - "bundled": true, + "resolved": false, + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -11295,19 +11405,22 @@ "dependencies": { "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "mimic-fn": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -11315,12 +11428,14 @@ }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mixin-deep": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -11329,7 +11444,8 @@ "dependencies": { "is-extendable": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -11339,7 +11455,8 @@ }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -11347,12 +11464,14 @@ }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "nanomatch": { "version": "1.2.9", - "bundled": true, + "resolved": false, + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -11371,14 +11490,16 @@ "dependencies": { "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "normalize-package-data": { "version": "2.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -11389,7 +11510,8 @@ }, "npm-run-path": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" @@ -11397,17 +11519,20 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-copy": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { "copy-descriptor": "^0.1.0", @@ -11417,7 +11542,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -11427,7 +11553,8 @@ }, "object-visit": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { "isobject": "^3.0.0" @@ -11435,7 +11562,8 @@ }, "object.pick": { "version": "1.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -11443,7 +11571,8 @@ }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" @@ -11451,7 +11580,8 @@ }, "optimist": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { "minimist": "~0.0.1", @@ -11460,12 +11590,14 @@ }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { "execa": "^0.7.0", @@ -11475,12 +11607,14 @@ }, "p-finally": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, "p-limit": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "dev": true, "requires": { "p-try": "^1.0.0" @@ -11488,7 +11622,8 @@ }, "p-locate": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -11496,12 +11631,14 @@ }, "p-try": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "parse-json": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -11509,12 +11646,14 @@ }, "pascalcase": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, "path-exists": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -11522,22 +11661,26 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-key": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, "path-type": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -11547,17 +11690,20 @@ }, "pify": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -11565,7 +11711,8 @@ }, "pkg-dir": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { "find-up": "^1.0.0" @@ -11573,7 +11720,8 @@ "dependencies": { "find-up": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -11584,17 +11732,20 @@ }, "posix-character-classes": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, "pseudomap": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "read-pkg": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -11604,7 +11755,8 @@ }, "read-pkg-up": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", @@ -11613,7 +11765,8 @@ "dependencies": { "find-up": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -11624,7 +11777,8 @@ }, "regex-not": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { "extend-shallow": "^3.0.2", @@ -11633,42 +11787,50 @@ }, "repeat-element": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", "dev": true }, "repeat-string": { "version": "1.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "require-directory": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "resolve-from": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", "dev": true }, "resolve-url": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, "ret": { "version": "0.1.15", - "bundled": true, + "resolved": false, + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, "right-align": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "optional": true, "requires": { @@ -11677,7 +11839,8 @@ }, "rimraf": { "version": "2.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "^7.0.5" @@ -11685,7 +11848,8 @@ }, "safe-regex": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { "ret": "~0.1.10" @@ -11693,17 +11857,20 @@ }, "semver": { "version": "5.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-value": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -11714,7 +11881,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -11724,7 +11892,8 @@ }, "shebang-command": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -11732,22 +11901,26 @@ }, "shebang-regex": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "slide": { "version": "1.1.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", "dev": true }, "snapdragon": { "version": "0.8.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { "base": "^0.11.1", @@ -11762,7 +11935,8 @@ "dependencies": { "debug": { "version": "2.6.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -11770,7 +11944,8 @@ }, "define-property": { "version": "0.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -11778,7 +11953,8 @@ }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -11788,7 +11964,8 @@ }, "snapdragon-node": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { "define-property": "^1.0.0", @@ -11798,7 +11975,8 @@ "dependencies": { "define-property": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -11806,7 +11984,8 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -11814,7 +11993,8 @@ }, "is-data-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -11822,7 +12002,8 @@ }, "is-descriptor": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -11832,14 +12013,16 @@ }, "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "snapdragon-util": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { "kind-of": "^3.2.0" @@ -11847,12 +12030,14 @@ }, "source-map": { "version": "0.5.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-resolve": { "version": "0.5.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", "dev": true, "requires": { "atob": "^2.1.1", @@ -11864,12 +12049,14 @@ }, "source-map-url": { "version": "0.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "spawn-wrap": { "version": "1.4.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", "dev": true, "requires": { "foreground-child": "^1.5.6", @@ -11882,7 +12069,8 @@ }, "spdx-correct": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -11891,12 +12079,14 @@ }, "spdx-exceptions": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -11905,12 +12095,14 @@ }, "spdx-license-ids": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "split-string": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { "extend-shallow": "^3.0.0" @@ -11918,7 +12110,8 @@ }, "static-extend": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { "define-property": "^0.2.5", @@ -11927,7 +12120,8 @@ "dependencies": { "define-property": { "version": "0.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -11937,7 +12131,8 @@ }, "string-width": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -11946,7 +12141,8 @@ }, "strip-ansi": { "version": "4.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -11954,7 +12150,8 @@ }, "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -11962,12 +12159,14 @@ }, "strip-eof": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "test-exclude": { "version": "4.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -11979,7 +12178,8 @@ }, "to-object-path": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11987,7 +12187,8 @@ }, "to-regex": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { "define-property": "^2.0.2", @@ -11998,7 +12199,8 @@ }, "to-regex-range": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -12007,7 +12209,8 @@ }, "uglify-js": { "version": "2.8.29", - "bundled": true, + "resolved": false, + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "optional": true, "requires": { @@ -12018,7 +12221,8 @@ "dependencies": { "yargs": { "version": "3.10.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "optional": true, "requires": { @@ -12032,13 +12236,15 @@ }, "uglify-to-browserify": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true, "optional": true }, "union-value": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -12049,7 +12255,8 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -12057,7 +12264,8 @@ }, "set-value": { "version": "0.4.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -12070,7 +12278,8 @@ }, "unset-value": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { "has-value": "^0.3.1", @@ -12079,7 +12288,8 @@ "dependencies": { "has-value": { "version": "0.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { "get-value": "^2.0.3", @@ -12089,7 +12299,8 @@ "dependencies": { "isobject": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" @@ -12099,19 +12310,22 @@ }, "has-values": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true } } }, "urix": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "use": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "dev": true, "requires": { "kind-of": "^6.0.2" @@ -12119,14 +12333,16 @@ "dependencies": { "kind-of": { "version": "6.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "validate-npm-package-license": { "version": "3.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { "spdx-correct": "^3.0.0", @@ -12135,7 +12351,8 @@ }, "which": { "version": "1.3.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", "dev": true, "requires": { "isexe": "^2.0.0" @@ -12143,23 +12360,27 @@ }, "which-module": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "window-size": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true, "optional": true }, "wordwrap": { "version": "0.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, "wrap-ansi": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", @@ -12168,12 +12389,14 @@ "dependencies": { "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -12181,7 +12404,8 @@ }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -12191,7 +12415,8 @@ }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -12201,12 +12426,14 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write-file-atomic": { "version": "1.3.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -12216,17 +12443,20 @@ }, "y18n": { "version": "3.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, "yallist": { "version": "2.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "11.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { "cliui": "^4.0.0", @@ -12245,12 +12475,14 @@ "dependencies": { "camelcase": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, "cliui": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { "string-width": "^2.1.1", @@ -12260,7 +12492,8 @@ }, "yargs-parser": { "version": "9.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { "camelcase": "^4.1.0" @@ -12270,7 +12503,8 @@ }, "yargs-parser": { "version": "8.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { "camelcase": "^4.1.0" @@ -12278,7 +12512,8 @@ "dependencies": { "camelcase": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true } } @@ -12385,14 +12620,6 @@ "make-iterator": "^1.0.0" } }, - "oidc-token-hash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-3.0.1.tgz", - "integrity": "sha512-oLnVSEcNZkw01sB5aFR+2iJmW4oyC1PIMJmd3FMBGDuPTy5ZtEuX5WNhKMRarJIMOq8NiOwIB6eJB9AhgYwBTg==", - "requires": { - "base64url": "^3.0.0" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -12423,36 +12650,6 @@ "format-util": "^1.0.3" } }, - "openid-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-2.1.0.tgz", - "integrity": "sha512-rYmoH0sXAJwvvmQiWj4TOpao20SJoRLIEHrs2ynBQIn7sE2G2oMEHActx0WkWl/VZf1y4RTGMYi9/etMqUgzFg==", - "requires": { - "base64url": "^3.0.0", - "got": "^8.3.1", - "lodash": "^4.17.10", - "lru-cache": "^4.1.3", - "node-jose": "^1.0.0", - "oidc-token-hash": "^3.0.1", - "uuid": "^3.2.1" - }, - "dependencies": { - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - } - } - }, "opn": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", @@ -12539,21 +12736,11 @@ "os-tmpdir": "^1.0.0" } }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, - "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" - }, "p-limit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", @@ -12591,14 +12778,6 @@ "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", "dev": true }, - "p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", @@ -12792,8 +12971,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "2.0.1", @@ -12803,8 +12981,7 @@ "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" }, "path-root": { "version": "0.1.1", @@ -12967,11 +13144,6 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - }, "prettier": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.1.tgz", @@ -13007,11 +13179,6 @@ "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=" }, - "promy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/promy/-/promy-0.1.0.tgz", - "integrity": "sha1-/xnDlT4QdM8D8i8/MkXIW3xxXUA=" - }, "promzard": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", @@ -13148,16 +13315,6 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, "quibble": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/quibble/-/quibble-0.5.5.tgz", @@ -13369,7 +13526,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, "requires": { "resolve": "^1.1.6" } @@ -13557,7 +13713,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "dev": true, "requires": { "path-parse": "^1.0.5" } @@ -13619,14 +13774,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -13817,6 +13964,16 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", @@ -14344,6 +14501,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, "requires": { "is-plain-obj": "^1.0.0" } @@ -14558,6 +14716,36 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, + "static-eval": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-0.2.3.tgz", + "integrity": "sha1-Aj8XrJ/uQm6niMEuo5IG3Bdfiyo=", + "requires": { + "escodegen": "~0.0.24" + }, + "dependencies": { + "escodegen": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.28.tgz", + "integrity": "sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M=", + "requires": { + "esprima": "~1.0.2", + "estraverse": "~1.3.0", + "source-map": ">= 0.1.2" + } + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=" + }, + "estraverse": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.3.2.tgz", + "integrity": "sha1-N8K4k+8T1yPydth41g2FNRUqbEI=" + } + } + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -14611,11 +14799,6 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -14944,7 +15127,8 @@ "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true }, "timers-ext": { "version": "0.1.5", @@ -15199,6 +15383,14 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", @@ -15323,6 +15515,11 @@ "debug": "^2.2.0" } }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "undertaker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", @@ -15472,19 +15669,6 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", @@ -15684,6 +15868,17 @@ "defaults": "^1.0.3" } }, + "websocket": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.26.tgz", + "integrity": "sha512-fjcrYDPIQxpTnqFQ9JjxUQcdvR89MFAOjPBlF+vjOt49w/XW4fJknUoMz/mDIn2eK1AdslVojcaOxOqyZZV8rw==", + "requires": { + "debug": "^2.2.0", + "nan": "^2.3.3", + "typedarray-to-buffer": "^3.1.2", + "yaeti": "^0.0.6" + } + }, "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", @@ -15895,6 +16090,11 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/package.json b/package.json index 01de6cee25..f348a0dda9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "dist" ], "dependencies": { + "@kubernetes/client-node": "^0.3.0", "ansi-escapes": "^3.1.0", "async-exit-hook": "^2.0.1", "axios": "^0.18.0", @@ -34,6 +35,7 @@ "dockerode": "^2.5.5", "elegant-spinner": "^1.0.1", "escape-string-regexp": "^1.0.5", + "execa": "^0.10.0", "fb-watchman": "^2.0.0", "fs-extra": "^6.0.1", "has-ansi": "^3.0.0", @@ -44,7 +46,6 @@ "js-yaml": "^3.12.0", "json-stringify-safe": "^5.0.1", "klaw": "^2.1.1", - "kubernetes-client": "^5.3.0", "log-symbols": "^2.2.0", "moment": "^2.22.2", "node-emoji": "^1.8.1", @@ -68,6 +69,7 @@ "@types/chai": "^4.1.3", "@types/dedent": "^0.7.0", "@types/dockerode": "^2.5.4", + "@types/execa": "^0.9.0", "@types/fs-extra": "^5.0.3", "@types/gulp": "^4.0.5", "@types/handlebars": "^4.0.38", diff --git a/src/plugins/kubernetes/actions.ts b/src/plugins/kubernetes/actions.ts index 140fdb0633..07179fe246 100644 --- a/src/plugins/kubernetes/actions.ts +++ b/src/plugins/kubernetes/actions.ts @@ -40,12 +40,10 @@ import { helpers, } from "../container" import { values, every, uniq } from "lodash" -import { deserializeKeys, serializeKeys, splitFirst, sleep } from "../../util/util" +import { deserializeValues, serializeValues, splitFirst, sleep } from "../../util/util" import { ServiceStatus } from "../../types/service" import { joiIdentifier } from "../../types/common" import { - apiGetOrNull, - apiPostOrPut, coreApi, } from "./api" import { @@ -97,10 +95,10 @@ export async function getEnvironmentStatus({ ctx, provider }: GetEnvironmentStat } const metadataNamespace = getMetadataNamespace(ctx, provider) - const namespacesStatus = await coreApi(context).namespaces.get() + const namespacesStatus = await coreApi(context).listNamespace() const namespace = await getAppNamespace(ctx, provider) - for (const n of namespacesStatus.items) { + for (const n of namespacesStatus.body.items) { if (n.metadata.name === namespace && n.status.phase === "Active") { statusDetail.namespaceReady = true } @@ -154,7 +152,8 @@ export async function destroyEnvironment({ ctx, provider, env }: DestroyEnvironm try { // Note: Need to call the delete method with an empty object - await coreApi(context).namespaces(namespace).delete({}) + // TODO: any cast is required until https://github.com/kubernetes-client/javascript/issues/52 is fixed + await coreApi(context).deleteNamespace(namespace, {}) } catch (err) { entry.setError(err.message) const availableNamespaces = await getAllAppNamespaces(context) @@ -207,12 +206,16 @@ export async function execInService( } // get a running pod - let res = await coreApi(context).namespaces(namespace).pods.get({ - qs: { - labelSelector: `service=${service.name}`, - }, - }) - const pod = res.items[0] + // NOTE: the awkward function signature called out here: https://github.com/kubernetes-client/javascript/issues/53 + const podsRes = await coreApi(context).listNamespacedPod( + namespace, + undefined, + undefined, + undefined, + undefined, + `service=${service.name}`, + ) + const pod = podsRes.body.items[0] if (!pod) { // This should not happen because of the prior status check, but checking to be sure @@ -222,7 +225,7 @@ export async function execInService( } // exec in the pod via kubectl - res = await kubectl(context, namespace).tty(["exec", "-it", pod.metadata.name, "--", ...command]) + const res = await kubectl(context, namespace).tty(["exec", "-it", pod.metadata.name, "--", ...command]) return { code: res.code, output: res.output } } @@ -301,21 +304,26 @@ export async function testModule( const ns = getMetadataNamespace(ctx, provider) const resultKey = getTestResultKey(module, testName, result.version) const body = { - body: { - apiVersion: "v1", - kind: "ConfigMap", - metadata: { - name: resultKey, - annotations: { - "garden.io/generated": "true", - }, + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + name: resultKey, + annotations: { + "garden.io/generated": "true", }, - type: "generic", - data: serializeKeys(testResult), }, + data: serializeValues(testResult), } - await apiPostOrPut(coreApi(context).namespaces(ns).configmaps, resultKey, body) + try { + await coreApi(context).createNamespacedConfigMap(ns, body) + } catch (err) { + if (err.response && err.response.statusCode === 409) { + await coreApi(context).patchNamespacedConfigMap(resultKey, ns, body) + } else { + throw err + } + } return testResult } @@ -326,8 +334,17 @@ export async function getTestResult( const context = provider.config.context const ns = getMetadataNamespace(ctx, provider) const resultKey = getTestResultKey(module, testName, version) - const res = await apiGetOrNull(coreApi(context).namespaces(ns).configmaps, resultKey) - return res && deserializeKeys(res.data) + + try { + const res = await coreApi(context).readNamespacedConfigMap(resultKey, ns) + return deserializeValues(res.body.data) + } catch (err) { + if (err.response && err.response.statusCode === 404) { + return null + } else { + throw err + } + } } export async function getServiceLogs( @@ -373,21 +390,30 @@ export async function getServiceLogs( export async function getConfig({ ctx, provider, key }: GetConfigParams) { const context = provider.config.context const ns = getMetadataNamespace(ctx, provider) - const res = await apiGetOrNull(coreApi(context).namespaces(ns).secrets, key.join(".")) - const value = res && Buffer.from(res.data.value, "base64").toString() - return { value } + + try { + const res = await coreApi(context).readNamespacedSecret(key.join("."), ns) + return { value: Buffer.from(res.body.data.value, "base64").toString() } + } catch (err) { + if (err.response && err.response.statusCode === 404) { + return { value: null } + } else { + throw err + } + } } export async function setConfig({ ctx, provider, key, value }: SetConfigParams) { // we store configuration in a separate metadata namespace, so that configs aren't cleared when wiping the namespace const context = provider.config.context const ns = getMetadataNamespace(ctx, provider) + const name = key.join(".") const body = { body: { apiVersion: "v1", kind: "Secret", metadata: { - name: key, + name, annotations: { "garden.io/generated": "true", }, @@ -397,7 +423,15 @@ export async function setConfig({ ctx, provider, key, value }: SetConfigParams) }, } - await apiPostOrPut(coreApi(context).namespaces(ns).secrets, key.join("."), body) + try { + await coreApi(context).createNamespacedSecret(ns, body) + } catch (err) { + if (err.response && err.response.statusCode === 409) { + await coreApi(context).patchNamespacedSecret(name, ns, body) + } else { + throw err + } + } return {} } @@ -405,10 +439,12 @@ export async function setConfig({ ctx, provider, key, value }: SetConfigParams) export async function deleteConfig({ ctx, provider, key }: DeleteConfigParams) { const context = provider.config.context const ns = getMetadataNamespace(ctx, provider) + const name = key.join(".") + try { - await coreApi(context).namespaces(ns).secrets(key.join(".")).delete() + await coreApi(context).deleteNamespacedSecret(name, ns, {}) } catch (err) { - if (err.code === 404) { + if (err.response && err.response.statusCode === 404) { return { found: false } } else { throw err diff --git a/src/plugins/kubernetes/api.ts b/src/plugins/kubernetes/api.ts index 342a68ac44..448debd016 100644 --- a/src/plugins/kubernetes/api.ts +++ b/src/plugins/kubernetes/api.ts @@ -6,54 +6,65 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import * as K8s from "kubernetes-client" +import { KubeConfig, Core_v1Api, Extensions_v1beta1Api, RbacAuthorization_v1Api } from "@kubernetes/client-node" +import { join } from "path" +import { readFileSync } from "fs" +import { safeLoad } from "js-yaml" +import { zip } from "lodash" -const cachedParams = {} +let kubeConfigStr: string +let kubeConfig: any -function getParams(context: string, namespace?: string) { - let params = cachedParams[namespace || ""] +const configs: { [context: string]: KubeConfig } = {} - if (!params) { - const config = K8s.config.loadKubeconfig() - params = K8s.config.fromKubeconfig(config, context) +// NOTE: be warned, the API of the client library is very likely to change - params.promises = true - params.namespace = namespace +function getConfig(context: string): KubeConfig { + if (!kubeConfigStr) { + kubeConfigStr = readFileSync(process.env.KUBECONFIG || join(process.env.HOME || "/home", ".kube", "config")) + .toString() + kubeConfig = safeLoad(kubeConfigStr) + } + + if (!configs[context]) { + const kc = new KubeConfig() + + kc.loadFromString(kubeConfigStr) + kc.setCurrentContext(context) - cachedParams[namespace || ""] = params + // FIXME: need to patch a bug in the library here (https://github.com/kubernetes-client/javascript/pull/54) + for (const [a, b] of zip(kubeConfig["clusters"] || [], kc.clusters)) { + if (a && a["cluster"]["insecure-skip-tls-verify"] === true) { + (b).skipTLSVerify = true + } + } + + configs[context] = kc } - return params + return configs[context] } -export function coreApi(context: string, namespace?: string): any { - return new K8s.Core(getParams(context, namespace)) -} +export function coreApi(context: string) { + const config = getConfig(context) + const k8sApi = new Core_v1Api(config.getCurrentCluster().server) + k8sApi.setDefaultAuthentication(config) -export function extensionsApi(context: string, namespace?: string): any { - return new K8s.Extensions(getParams(context, namespace)) + return k8sApi } -export async function apiPostOrPut(api: any, name: string, body: object) { - try { - await api.post(body) - } catch (err) { - if (err.code === 409) { - await api(name).put(body) - } else { - throw err - } - } +export function extensionsApi(context: string) { + const config = getConfig(context) + const k8sApi = new Extensions_v1beta1Api(config.getCurrentCluster().server) + k8sApi.setDefaultAuthentication(config) + + return k8sApi } -export async function apiGetOrNull(api: any, name: string) { - try { - return await api(name).get() - } catch (err) { - if (err.code === 404) { - return null - } else { - throw err - } - } +export function rbacApi(context: string) { + const config = getConfig(context) + const k8sApi = new RbacAuthorization_v1Api(config.getCurrentCluster().server) + k8sApi.setDefaultAuthentication(config) + + return k8sApi } diff --git a/src/plugins/kubernetes/namespace.ts b/src/plugins/kubernetes/namespace.ts index a7c0da3bcb..90424c748b 100644 --- a/src/plugins/kubernetes/namespace.ts +++ b/src/plugins/kubernetes/namespace.ts @@ -19,15 +19,14 @@ import { name as providerName } from "./kubernetes" import { AuthenticationError } from "../../exceptions" export async function createNamespace(context: string, namespace: string) { - await coreApi(context).namespaces.post({ - body: { - apiVersion: "v1", - kind: "Namespace", - metadata: { - name: namespace, - annotations: { - "garden.io/generated": "true", - }, + // TODO: the types for all the create functions in the library are currently broken + await coreApi(context).createNamespace({ + apiVersion: "v1", + kind: "Namespace", + metadata: { + name: namespace, + annotations: { + "garden.io/generated": "true", }, }, }) @@ -62,8 +61,8 @@ export function getMetadataNamespace(ctx: PluginContext, provider: KubernetesPro } export async function getAllAppNamespaces(context: string): Promise { - const allNamespaces = await coreApi(context).namespaces.get() - return allNamespaces.items + const allNamespaces = await coreApi(context).listNamespace() + return allNamespaces.body.items .map(n => n.metadata.name) .filter(n => n.startsWith("garden--")) } diff --git a/src/plugins/kubernetes/status.ts b/src/plugins/kubernetes/status.ts index 4ef9949144..c97fc068f9 100644 --- a/src/plugins/kubernetes/status.ts +++ b/src/plugins/kubernetes/status.ts @@ -34,7 +34,6 @@ export async function checkDeploymentStatus( { ctx: PluginContext, provider: Provider, service: ContainerService, resourceVersion?: number }, ): Promise { const context = provider.config.context - const type = service.spec.daemon ? "daemonsets" : "deployments" const hostname = getServiceHostname(ctx, provider, service) const namespace = await getAppNamespace(ctx, provider) @@ -61,10 +60,15 @@ export async function checkDeploymentStatus( let statusRes let status + const extApi = extensionsApi(context) + const apiFunc = service.spec.daemon + ? extApi.readNamespacedDaemonSet + : extApi.readNamespacedDeployment + try { - statusRes = await extensionsApi(context).namespaces(namespace)[type](service.name).get() + statusRes = (await apiFunc.apply(extApi, [service.name, namespace])).body } catch (err) { - if (err.code === 404) { + if (err.response && err.response.statusCode === 404) { // service is not running return out } else { @@ -82,7 +86,7 @@ export async function checkDeploymentStatus( // TODO: try to come up with something more efficient. may need to wait for newer k8s version. // note: the resourceVersion parameter does not appear to work... - const eventsRes = await coreApi(context).namespaces(namespace).events.get() + const eventsRes = await coreApi(context).listNamespacedEvent(namespace) // const eventsRes = await this.kubeApi( // "GET", @@ -96,7 +100,7 @@ export async function checkDeploymentStatus( // ) // look for errors and warnings in the events for the service, abort if we find any - const events = eventsRes.items + const events = eventsRes.body.items for (let event of events) { const eventVersion = parseInt(event.metadata.resourceVersion, 10) diff --git a/src/util/util.ts b/src/util/util.ts index 5853784f86..41cb9c711e 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -339,7 +339,7 @@ export function omitUndefined(o: object) { return pickBy(o, (v: any) => v !== undefined) } -export function serializeObject(o: object) { +export function serializeObject(o: any): string { return Buffer.from(Cryo.stringify(o)).toString("base64") } @@ -347,11 +347,11 @@ export function deserializeObject(s: string) { return Cryo.parse(Buffer.from(s, "base64")) } -export function serializeKeys(o: object) { +export function serializeValues(o: { [key: string]: any }): { [key: string]: string } { return mapValues(o, serializeObject) } -export function deserializeKeys(o: object) { +export function deserializeValues(o: object) { return mapValues(o, deserializeObject) } From 122e6ddad6314a4fa47902b2b9d08f8bec8e05e1 Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Wed, 13 Jun 2018 23:38:13 +0200 Subject: [PATCH 6/6] feat(k8s): add helm module type Note: This initial implementation doesn't use helm for installing charts, just for fetching and rendering the manifests. We'll change that in following steps, eventually removing the specs module. --- bin/bootstrap-osx | 2 +- docs/introduction/getting-started.md | 1 + package-lock.json | 77 ++----- package.json | 2 + src/constants.ts | 1 + src/plugins/kubernetes/deployment.ts | 2 + src/plugins/kubernetes/helm.ts | 218 ++++++++++++++++++ src/plugins/kubernetes/kubectl.ts | 26 ++- src/plugins/kubernetes/kubernetes.ts | 2 + src/plugins/kubernetes/local.ts | 102 ++++---- src/plugins/kubernetes/specs-module.ts | 154 ++++++++++--- src/util/util.ts | 15 ++ .../system/kubernetes-dashboard/garden.yml | 146 +----------- 13 files changed, 473 insertions(+), 275 deletions(-) create mode 100644 src/plugins/kubernetes/helm.ts diff --git a/bin/bootstrap-osx b/bin/bootstrap-osx index 7eeff97621..66b8f661f5 100755 --- a/bin/bootstrap-osx +++ b/bin/bootstrap-osx @@ -1,7 +1,7 @@ #!/usr/bin/env bash # install/update homebrew dependencies -BREW_DEPS="cmake git kubectl stern rsync watchman icu4c pkg-config yarn" +BREW_DEPS="cmake git kubectl kubernetes-helm stern rsync watchman icu4c pkg-config yarn" brew update brew install ${BREW_DEPS} diff --git a/docs/introduction/getting-started.md b/docs/introduction/getting-started.md index 9297ef0bbe..5731e7a7e9 100644 --- a/docs/introduction/getting-started.md +++ b/docs/introduction/getting-started.md @@ -10,6 +10,7 @@ You need the following dependencies on your local machine to use Garden: * Git * rsync * [Watchman](https://facebook.github.io/watchman/docs/install.html) +* [Helm](https://github.com/kubernetes/helm) * Local installation of Kubernetes ### OSX diff --git a/package-lock.json b/package-lock.json index 9866aecd6a..e07cb7ba2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2491,6 +2491,12 @@ "integrity": "sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==", "dev": true }, + "@types/deep-diff": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@types/deep-diff/-/deep-diff-0.0.31.tgz", + "integrity": "sha512-9t14b0HjrvzFEhHZ4ffs/HY6U/PjGEPZYEc/sFG/uTZh27YRpeZXyUpTZP5kyPUMb5Orn969puL8KXTwGtLs7w==", + "dev": true + }, "@types/dockerode": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-2.5.4.tgz", @@ -4830,23 +4836,17 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" }, "css": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", - "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz", + "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==", "dev": true, "requires": { "inherits": "^2.0.1", "source-map": "^0.1.38", - "source-map-resolve": "^0.3.0", + "source-map-resolve": "^0.5.1", "urix": "^0.1.0" }, "dependencies": { - "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", - "dev": true - }, "source-map": { "version": "0.1.43", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", @@ -4855,24 +4855,6 @@ "requires": { "amdefine": ">=0.0.4" } - }, - "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", - "dev": true, - "requires": { - "atob": "~1.1.0", - "resolve-url": "~0.2.1", - "source-map-url": "~0.3.0", - "urix": "~0.1.0" - } - }, - "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", - "dev": true } } }, @@ -4991,6 +4973,11 @@ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" }, + "deep-diff": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-1.0.1.tgz", + "integrity": "sha512-Vkn+eQK6H63gObVi3KWmPMb4RdzMpfdp5t0HNppq8Oc7xbwmvBy5BIHsEYSXOiS9Lr/W+3lF020zyPTsGfea4g==" + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -6165,9 +6152,9 @@ } }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, @@ -6278,13 +6265,6 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -6494,13 +6474,13 @@ "optional": true }, "rc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", - "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, "requires": { - "deep-extend": "~0.4.0", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -6612,13 +6592,6 @@ "ansi-regex": "^2.0.0" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, "tar": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", @@ -9020,9 +8993,9 @@ } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "lodash._basecopy": { "version": "3.0.1", diff --git a/package.json b/package.json index f348a0dda9..f50815f1a5 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "cli-highlight": "^2.0.0", "cryo": "0.0.6", "dedent": "^0.7.0", + "deep-diff": "^1.0.1", "deep-map": "^1.5.0", "dockerode": "^2.5.5", "elegant-spinner": "^1.0.1", @@ -68,6 +69,7 @@ "@types/bluebird": "^3.5.20", "@types/chai": "^4.1.3", "@types/dedent": "^0.7.0", + "@types/deep-diff": "0.0.31", "@types/dockerode": "^2.5.4", "@types/execa": "^0.9.0", "@types/fs-extra": "^5.0.3", diff --git a/src/constants.ts b/src/constants.ts index 1ee9a4c982..6636e4a823 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -17,6 +17,7 @@ export const DEFAULT_NAMESPACE = "default" export const DEFAULT_PORT_PROTOCOL = "TCP" export const GARDEN_ANNOTATION_PREFIX = "garden.io/" +export const GARDEN_ANNOTATION_KEYS_SERVICE = GARDEN_ANNOTATION_PREFIX + "service" export const GARDEN_ANNOTATION_KEYS_VERSION = GARDEN_ANNOTATION_PREFIX + "version" export const DEFAULT_TEST_TIMEOUT = 60 * 1000 diff --git a/src/plugins/kubernetes/deployment.ts b/src/plugins/kubernetes/deployment.ts index 4ec9e69dc8..bf9663f8df 100644 --- a/src/plugins/kubernetes/deployment.ts +++ b/src/plugins/kubernetes/deployment.ts @@ -101,6 +101,8 @@ export async function createDeployment(service: ContainerService, runtimeContext labels: [], }, spec: { + // TODO: set this for non-system pods + // automountServiceAccountToken: false, // this prevents the pod from accessing the kubernetes API containers: [], // TODO: make restartPolicy configurable restartPolicy: "Always", diff --git a/src/plugins/kubernetes/helm.ts b/src/plugins/kubernetes/helm.ts new file mode 100644 index 0000000000..5d7da639da --- /dev/null +++ b/src/plugins/kubernetes/helm.ts @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2018 Garden Technologies, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import execa = require("execa") +import * as Joi from "joi" +import { + safeLoad, + safeLoadAll, +} from "js-yaml" +import { set } from "lodash" +import { + join, + resolve, +} from "path" +import { PluginContext } from "../../plugin-context" +import { + joiArray, + joiIdentifier, + joiPrimitive, + Primitive, + validate, +} from "../../types/common" +import { + Module, + ModuleConfig, +} from "../../types/module" +import { + ModuleActions, + Provider, +} from "../../types/plugin/plugin" +import { + BuildModuleParams, + DeployServiceParams, + GetModuleBuildStatusParams, + GetServiceStatusParams, + ParseModuleParams, +} from "../../types/plugin/params" +import { + BuildResult, + ParseModuleResult, +} from "../../types/plugin/outputs" +import { + Service, + ServiceConfig, + ServiceSpec, + ServiceStatus, +} from "../../types/service" +import { dumpYaml } from "../../util/util" +import { KubernetesProvider } from "./kubernetes" +import { getAppNamespace } from "./namespace" +import { + kubernetesSpecHandlers, + KubernetesSpecsModule, + KubernetesSpecsModuleSpec, + KubernetesSpecsServiceSpec, +} from "./specs-module" +import { GARDEN_SYSTEM_NAMESPACE } from "./system" + +export interface HelmServiceSpec extends ServiceSpec { + chart: string + dependencies: string[] + version?: string + parameters: { [key: string]: Primitive } +} + +export type HelmModuleSpec = HelmServiceSpec + +export class HelmModule extends Module { } + +const parameterValueSchema = Joi.alternatives( + joiPrimitive(), + Joi.array().items(Joi.lazy(() => parameterValueSchema)), + Joi.object().pattern(/.+/, Joi.lazy(() => parameterValueSchema)), +) + +const helmModuleSpecSchema = Joi.object().keys({ + // TODO: support placing a helm chart in the module directory + chart: Joi.string() + .required() + .description("A valid Helm chart name or URI."), + dependencies: joiArray(joiIdentifier()) + .description("List of names of services that should be deployed before this chart."), + version: Joi.string() + .description("The chart version to deploy."), + parameters: Joi.object() + .pattern(/.+/, parameterValueSchema) + .default(() => ({}), "{}") + .description( + "Map of parameters to pass to Helm when rendering the templates. May include arrays and nested objects.", + ), +}) + +export const helmHandlers: Partial> = { + async parseModule({ moduleConfig }: ParseModuleParams): Promise { + moduleConfig.spec = validate( + moduleConfig.spec, + helmModuleSpecSchema, + { context: `helm module ${moduleConfig.name}` }, + ) + + const { chart, version, parameters, dependencies } = moduleConfig.spec + + const services: ServiceConfig[] = [{ + name: moduleConfig.name, + dependencies, + outputs: {}, + spec: { chart, version, parameters, dependencies }, + }] + + // TODO: make sure at least either a chart is specified, or module contains a helm chart + return { + module: moduleConfig, + services, + tests: [], + } + }, + + async getModuleBuildStatus({ }: GetModuleBuildStatusParams) { + return { ready: false } + }, + + buildModule, + + async getServiceStatus( + { ctx, env, provider, service, logEntry }: GetServiceStatusParams, + ): Promise { + await buildModule({ ctx, env, provider, module: service.module, logEntry }) + const specsService = await makeSpecsService(ctx, provider, service) + + return kubernetesSpecHandlers.getServiceStatus({ + ctx, env, provider, logEntry, + module: specsService.module, + service: specsService, + }) + }, + + async deployService({ ctx, env, provider, service }: DeployServiceParams): Promise { + const specsService = await makeSpecsService(ctx, provider, service) + const runtimeContext = await specsService.prepareRuntimeContext() + + return kubernetesSpecHandlers.deployService({ + ctx, env, provider, + module: specsService.module, + service: specsService, + runtimeContext, + }) + }, +} + +async function buildModule({ ctx, provider, module, logEntry }: BuildModuleParams): Promise { + const buildPath = await module.getBuildPath() + const config = module.config + + // fetch the chart + const fetchArgs = ["fetch", "--destination", resolve(buildPath, ".."), "--untar", config.spec.chart] + if (config.spec.version) { + fetchArgs.push("--version", config.spec.version) + } + logEntry && logEntry.setState("Fetching chart...") + await helm(provider, ...fetchArgs) + + // create the values.yml file + logEntry && logEntry.setState("Preparing chart...") + const values = safeLoad(await helm(provider, "inspect", "values", buildPath)) || {} + Object.entries(config.spec.parameters).map(([k, v]) => set(values, k, v)) + + const valuesPath = getValuesPath(buildPath) + dumpYaml(valuesPath, values) + + // make sure the template renders okay + await getSpecs(ctx, provider, module) + + return { fresh: true } +} + +export function helm(provider: KubernetesProvider, ...args: string[]) { + return execa.stdout("helm", [ + "--tiller-namespace", GARDEN_SYSTEM_NAMESPACE, + "--kube-context", provider.config.context, + ...args, + ]) +} + +function getValuesPath(buildPath: string) { + return join(buildPath, "garden-values.yml") +} + +async function getSpecs(ctx: PluginContext, provider: Provider, module: Module) { + const buildPath = await module.getBuildPath() + const valuesPath = getValuesPath(buildPath) + + return safeLoadAll(await helm(provider, + "template", + "--name", module.name, + "--namespace", await getAppNamespace(ctx, provider), + "--values", valuesPath, + buildPath, + )) +} + +async function makeSpecsService( + ctx: PluginContext, provider: Provider, service: Service, +): Promise> { + const specs = await getSpecs(ctx, provider, service.module) + const spec = { specs } + + const config: ModuleConfig = { ...service.module.config, spec } + const specsService: ServiceConfig = { ...service.config, spec } + + const module = new KubernetesSpecsModule(ctx, config, [specsService], []) + + return Service.factory(ctx, module, service.name) +} diff --git a/src/plugins/kubernetes/kubectl.ts b/src/plugins/kubernetes/kubectl.ts index b6d50050d2..e3141aac87 100644 --- a/src/plugins/kubernetes/kubectl.ts +++ b/src/plugins/kubernetes/kubectl.ts @@ -9,7 +9,7 @@ import chalk from "chalk" import { ChildProcess, spawn } from "child_process" import { extend } from "lodash" -import { spawnPty } from "../../util/util" +import { encodeYamlMulti, spawnPty } from "../../util/util" import { RuntimeError } from "../../exceptions" import { getLogger } from "../../logger/logger" import hasAnsi = require("has-ansi") @@ -29,6 +29,13 @@ export interface KubectlOutput { stderr?: string, } +export interface ApplyOptions { + dryRun?: boolean, + force?: boolean, + pruneSelector?: string, + namespace?: string, +} + export const KUBECTL_DEFAULT_TIMEOUT = 600 export class Kubectl { @@ -156,18 +163,21 @@ export function kubectl(context: string, namespace?: string) { return new Kubectl({ context, namespace }) } -export async function apply( - context: string, obj: any, - { dryRun = false, force = false, namespace }: { dryRun?: boolean, force?: boolean, namespace?: string } = {}, +export async function apply(context: string, spec: object, params: ApplyOptions) { + return applyMany(context, [spec], params) +} + +export async function applyMany( + context: string, specs: object[], + { dryRun = false, force = false, namespace, pruneSelector }: ApplyOptions = {}, ) { - const data = Buffer.from(JSON.stringify(obj)) + const data = Buffer.from(encodeYamlMulti(specs)) let args = ["apply"] dryRun && args.push("--dry-run") force && args.push("--force") - args.push("--output=json") - args.push("-f") - args.push("-") + pruneSelector && args.push("--prune", "--selector", pruneSelector) + args.push("--output=json", "-f", "-") const result = await kubectl(context, namespace).call(args, { data }) diff --git a/src/plugins/kubernetes/kubernetes.ts b/src/plugins/kubernetes/kubernetes.ts index 7ce13f4427..083b6a1141 100644 --- a/src/plugins/kubernetes/kubernetes.ts +++ b/src/plugins/kubernetes/kubernetes.ts @@ -37,6 +37,7 @@ import { } from "./actions" import { deployService } from "./deployment" import { kubernetesSpecHandlers } from "./specs-module" +import { helmHandlers } from "./helm" export const name = "kubernetes" @@ -102,6 +103,7 @@ export function gardenPlugin({ config }: { config: KubernetesConfig }): GardenPl getServiceLogs, }, "kubernetes-specs": kubernetesSpecHandlers, + helm: helmHandlers, }, } } diff --git a/src/plugins/kubernetes/local.ts b/src/plugins/kubernetes/local.ts index 6d92ef13dd..f510a13b61 100644 --- a/src/plugins/kubernetes/local.ts +++ b/src/plugins/kubernetes/local.ts @@ -16,7 +16,7 @@ import * as Joi from "joi" import { join } from "path" import { PluginError } from "../../exceptions" import { DeployTask } from "../../tasks/deploy" -import { validate } from "../../types/common" +import { Environment, validate } from "../../types/common" import { GardenPlugin, } from "../../types/plugin/plugin" @@ -33,6 +33,7 @@ import { import { gardenPlugin as k8sPlugin, KubernetesConfig, + KubernetesProvider, } from "./kubernetes" import { getSystemGarden, @@ -40,6 +41,7 @@ import { } from "./system" import { readFile } from "fs-extra" import { processServices } from "../../process" +import { LogEntry } from "../../logger/logger" // TODO: split this into separate plugins to handle Docker for Mac and Minikube @@ -67,52 +69,61 @@ export async function getLocalEnvironmentStatus( return status } -async function configureLocalEnvironment( - { ctx, provider, env, force, status, logEntry }: ConfigureEnvironmentParams, +async function configureSystemEnvironment( + { provider, env, force, logEntry }: + { provider: KubernetesProvider, env: Environment, force: boolean, logEntry?: LogEntry }, ) { - await configureEnvironment({ ctx, provider, env, force, status, logEntry }) + const sysGarden = await getSystemGarden(provider) + const sysCtx = sysGarden.pluginContext + const sysProvider: KubernetesProvider = { + name: provider.name, + config: findByName(sysGarden.config.providers, provider.name)!, + } - if (!isSystemGarden(provider)) { - const sysGarden = await getSystemGarden(provider) - const sysCtx = sysGarden.pluginContext - const sysProvider = { - name: provider.name, - config: findByName(sysGarden.config.providers, provider.name)!, - } + await execa("helm", ["init", "--client-only"]) - const sysStatus = await getEnvironmentStatus({ - ctx: sysCtx, - provider: sysProvider, - env, - }) + const sysStatus = await getEnvironmentStatus({ + ctx: sysCtx, + provider: sysProvider, + env, + }) - await configureEnvironment({ - ctx: sysCtx, - env: sysGarden.getEnvironment(), - provider: sysProvider, - force, - status: sysStatus, - logEntry, - }) + await configureEnvironment({ + ctx: sysCtx, + env: sysGarden.getEnvironment(), + provider: sysProvider, + force, + status: sysStatus, + logEntry, + }) + + const services = await sysCtx.getServices(provider.config._systemServices) - const services = await sysCtx.getServices(provider.config._systemServices) + const results = await processServices({ + services, + pluginContext: sysCtx, + watch: false, + process: async (service) => { + return [await DeployTask.factory({ ctx: sysCtx, service, force, forceBuild: false })] + }, + }) - const results = await processServices({ - services, - pluginContext: ctx, - watch: false, - process: async (service) => { - return [await DeployTask.factory({ ctx: sysCtx, service, force, forceBuild: false })] - }, + const failed = values(results.taskResults).filter(r => !!r.error).length + + if (failed) { + throw new PluginError(`local-kubernetes: ${failed} errors occurred when configuring environment`, { + results, }) + } +} - const failed = values(results.taskResults).filter(r => !!r.error).length +async function configureLocalEnvironment( + { ctx, provider, env, force, status, logEntry }: ConfigureEnvironmentParams, +) { + await configureEnvironment({ ctx, provider, env, force, status, logEntry }) - if (failed) { - throw new PluginError(`local-kubernetes: ${failed} errors occurred when configuring environments`, { - results, - }) - } + if (!isSystemGarden(provider)) { + await configureSystemEnvironment({ provider, env, force, logEntry }) } return {} @@ -126,6 +137,10 @@ async function getKubeConfig(): Promise { } } +/** + * Automatically set docker environment variables for minikube + * TODO: it would be better to explicitly provide those to docker instead of using process.env + */ async function setMinikubeDockerEnv() { const minikubeEnv = await execa.stdout("minikube", ["docker-env", "--shell=bash"]) for (const line of minikubeEnv.split("\n")) { @@ -192,7 +207,7 @@ export async function gardenPlugin({ config, logEntry }): Promise } if (context === "minikube") { - await execa("minikube", ["addons", "enable", "ingress"]) + await execa("minikube", ["config", "set", "WantUpdateNotification", "false"]) ingressHostname = config.ingressHostname @@ -202,12 +217,13 @@ export async function gardenPlugin({ config, logEntry }): Promise ingressHostname = minikubeIp + ".nip.io" } + await Promise.all([ + execa("minikube", ["addons", "enable", "ingress"]), + setMinikubeDockerEnv(), + ]) + ingressPort = 80 systemServices = [] - - // automatically set docker environment variables for minikube - // TODO: it would be better to explicitly provide those to docker instead of using process.env - await setMinikubeDockerEnv() } else { ingressHostname = config.ingressHostname || "local.app.garden" ingressPort = 32000 diff --git a/src/plugins/kubernetes/specs-module.ts b/src/plugins/kubernetes/specs-module.ts index 2ec2a2f34d..89f8394866 100644 --- a/src/plugins/kubernetes/specs-module.ts +++ b/src/plugins/kubernetes/specs-module.ts @@ -7,8 +7,16 @@ */ import Bluebird = require("bluebird") +import { + isEqual, + set, + zip, +} from "lodash" import * as Joi from "joi" -import { GARDEN_ANNOTATION_KEYS_VERSION } from "../../constants" +import { + GARDEN_ANNOTATION_KEYS_SERVICE, + GARDEN_ANNOTATION_KEYS_VERSION, +} from "../../constants" import { joiIdentifier, validate, @@ -17,7 +25,6 @@ import { Module, ModuleSpec, } from "../../types/module" -import { ModuleActions } from "../../types/plugin/plugin" import { ParseModuleResult, } from "../../types/plugin/outputs" @@ -27,25 +34,44 @@ import { ParseModuleParams, } from "../../types/plugin/params" import { + Service, ServiceConfig, - ServiceSpec, ServiceStatus, } from "../../types/service" import { TestConfig, TestSpec, } from "../../types/test" +import { TreeVersion } from "../../vcs/base" import { - apply, + applyMany, } from "./kubectl" import { getAppNamespace } from "./namespace" +import { coreApi, extensionsApi, rbacApi } from "./api" +import { KubernetesProvider } from "./kubernetes" +import { PluginContext } from "../../plugin-context" +import { ConfigurationError } from "../../exceptions" export interface KubernetesSpecsModuleSpec extends ModuleSpec { specs: any[], } -export class KubernetesSpecsModule extends Module { } +export interface KubernetesSpecsServiceSpec extends KubernetesSpecsModuleSpec { } + +export class KubernetesSpecsModule extends Module { } +export interface K8sSpec { + apiVersion: string + kind: string + metadata: { + annotations?: object, + name: string, + namespace?: string, + labels?: object, + } +} + +// TODO: use actual k8s swagger schemas from @kubernetes/client-node to validate const k8sSpecSchema = Joi.object().keys({ apiVersion: Joi.string().required(), kind: Joi.string().required(), @@ -59,10 +85,10 @@ const k8sSpecSchema = Joi.object().keys({ const k8sSpecsSchema = Joi.array().items(k8sSpecSchema).min(1) -export const kubernetesSpecHandlers: Partial = { +export const kubernetesSpecHandlers = { async parseModule({ moduleConfig }: ParseModuleParams): Promise { // TODO: check that each spec namespace is the same as on the project, if specified - const services: ServiceConfig[] = [{ + const services: ServiceConfig[] = [{ name: moduleConfig.name, dependencies: [], outputs: {}, @@ -83,20 +109,18 @@ export const kubernetesSpecHandlers: Partial = { getServiceStatus: async ( { ctx, provider, service }: GetServiceStatusParams, ): Promise => { - const context = provider.config.context const namespace = await getAppNamespace(ctx, provider) const currentVersion = await service.module.getVersion() + const specs = await prepareSpecs(service, namespace, currentVersion) - const dryRunOutputs = await Bluebird.map( - service.module.spec.specs, - (spec) => apply(context, spec, { dryRun: true, namespace }), - ) + const existingSpecs = await Bluebird.map(specs, spec => getSpec(ctx, provider, spec)) - for (const dryRunOutput of dryRunOutputs) { - const annotations = dryRunOutput.metadata.annotations || {} - const version: string = annotations[GARDEN_ANNOTATION_KEYS_VERSION] + for (const [spec, existingSpec] of zip(specs, existingSpecs)) { + const lastApplied = existingSpec && JSON.parse( + existingSpec.metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"], + ) - if (!version || version !== currentVersion.versionString) { + if (!isEqual(spec, lastApplied)) { // TODO: return more complete information. for now we just need to signal whether the deployed specs are current return {} } @@ -109,22 +133,92 @@ export const kubernetesSpecHandlers: Partial = { const context = provider.config.context const namespace = await getAppNamespace(ctx, provider) const currentVersion = await service.module.getVersion() + const specs = await prepareSpecs(service, namespace, currentVersion) - await Bluebird.each(service.module.spec.specs, async (spec) => { - const annotatedSpec = { - metadata: {}, - ...spec, - } - - if (!annotatedSpec.metadata.annotations) { - annotatedSpec.metadata.annotations = { [GARDEN_ANNOTATION_KEYS_VERSION]: currentVersion.versionString } - } else { - annotatedSpec.metadata.annotations[GARDEN_ANNOTATION_KEYS_VERSION] = currentVersion.versionString - } - - await apply(context, annotatedSpec, { namespace }) - }) + await applyMany(context, specs, { namespace, pruneSelector: `${GARDEN_ANNOTATION_KEYS_SERVICE}=${service.name}` }) return {} }, } + +async function prepareSpecs(service: Service, namespace: string, version: TreeVersion) { + return service.module.spec.specs.map((rawSpec) => { + const spec = { + metadata: {}, + ...rawSpec, + } + + spec.metadata.namespace = namespace + + set(spec, ["metadata", "annotations", GARDEN_ANNOTATION_KEYS_VERSION], version.versionString) + set(spec, ["metadata", "annotations", GARDEN_ANNOTATION_KEYS_SERVICE], service.name) + set(spec, ["metadata", "labels", GARDEN_ANNOTATION_KEYS_SERVICE], service.name) + + return spec + }) +} + +async function apiReadBySpec(ctx: PluginContext, provider: KubernetesProvider, spec: K8sSpec) { + // this is just awful, sorry. any better ideas? - JE + const context = provider.config.context + const namespace = await getAppNamespace(ctx, provider) + const name = spec.metadata.name + + const core = coreApi(context) + const ext = extensionsApi(context) + const rbac = rbacApi(context) + + switch (spec.kind) { + case "ConfigMap": + return core.readNamespacedConfigMap(name, namespace) + case "Endpoints": + return core.readNamespacedEndpoints(name, namespace) + case "LimitRange": + return core.readNamespacedLimitRange(name, namespace) + case "PersistentVolumeClaim": + return core.readNamespacedPersistentVolumeClaim(name, namespace) + case "Pod": + return core.readNamespacedPod(name, namespace) + case "PodTemplate": + return core.readNamespacedPodTemplate(name, namespace) + case "ReplicationController": + return core.readNamespacedReplicationController(name, namespace) + case "ResourceQuota": + return core.readNamespacedResourceQuota(name, namespace) + case "Secret": + return core.readNamespacedSecret(name, namespace) + case "Service": + return core.readNamespacedService(name, namespace) + case "ServiceAccount": + return core.readNamespacedServiceAccount(name, namespace) + case "DaemonSet": + return ext.readNamespacedDaemonSet(name, namespace) + case "Deployment": + return ext.readNamespacedDeployment(name, namespace) + case "Ingress": + return ext.readNamespacedIngress(name, namespace) + case "ReplicaSet": + return ext.readNamespacedReplicaSet(name, namespace) + case "Role": + return rbac.readNamespacedRole(name, namespace) + case "RoleBinding": + return rbac.readNamespacedRoleBinding(name, namespace) + default: + throw new ConfigurationError(`Unsupported Kubernetes spec kind: ${spec.kind}`, { + spec, + }) + } +} + +async function getSpec(ctx: PluginContext, provider: KubernetesProvider, spec: K8sSpec) { + try { + const res = await apiReadBySpec(ctx, provider, spec) + return res.body + } catch (err) { + if (err.response && err.response.statusCode === 404) { + return null + } else { + throw err + } + } +} diff --git a/src/util/util.ts b/src/util/util.ts index 41cb9c711e..03b4c44f42 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -27,6 +27,7 @@ import { isArray, isPlainObject, extend, mapValues, pickBy } from "lodash" import highlight from "cli-highlight" import chalk from "chalk" import hasAnsi = require("has-ansi") +import { safeDump } from "js-yaml" // shim to allow async generator functions if (typeof (Symbol as any).asyncIterator === "undefined") { @@ -311,6 +312,20 @@ export async function dumpYaml(yamlPath, data) { return writeFile(yamlPath, yaml.safeDump(data, { noRefs: true })) } +/** + * Encode multiple objects as one multi-doc YAML file + */ +export function encodeYamlMulti(objects: object[]) { + return objects.map(s => safeDump(s) + "---\n").join("") +} + +/** + * Encode and write multiple objects as a multi-doc YAML file + */ +export async function dumpYamlMulti(yamlPath: string, objects: object[]) { + return writeFile(yamlPath, encodeYamlMulti(objects)) +} + /** * Splits the input string on the first occurrence of `delimiter`. */ diff --git a/static/kubernetes/system/kubernetes-dashboard/garden.yml b/static/kubernetes/system/kubernetes-dashboard/garden.yml index fe51f76d14..9aabe4aaf9 100644 --- a/static/kubernetes/system/kubernetes-dashboard/garden.yml +++ b/static/kubernetes/system/kubernetes-dashboard/garden.yml @@ -1,144 +1,8 @@ module: description: Kubernetes dashboard configuration name: kubernetes-dashboard - type: kubernetes-specs - specs: - # ------------------- Dashboard Secret ------------------- # - - apiVersion: v1 - kind: Secret - metadata: - labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard-certs - namespace: garden-system - type: Opaque - # ------------------- Dashboard Service Account ------------------- # - - apiVersion: v1 - kind: ServiceAccount - metadata: - labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard - namespace: garden-system - # ------------------- Dashboard Role & Role Binding ------------------- # - - kind: Role - apiVersion: rbac.authorization.k8s.io/v1 - metadata: - labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard-minimal - namespace: garden-system - rules: - # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret. - - apiGroups: [""] - resources: ["secrets"] - verbs: ["create"] - # Allow Dashboard to create 'kubernetes-dashboard-settings' config map. - - apiGroups: [""] - resources: ["configmaps"] - verbs: ["create"] - # Allow Dashboard to get, update and delete Dashboard exclusive secrets. - - apiGroups: [""] - resources: ["secrets"] - resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"] - verbs: ["get", "update", "delete"] - # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. - - apiGroups: [""] - resources: ["configmaps"] - resourceNames: ["kubernetes-dashboard-settings"] - verbs: ["get", "update"] - # Allow Dashboard to get metrics from heapster. - - apiGroups: [""] - resources: ["services"] - resourceNames: ["heapster"] - verbs: ["proxy"] - - apiGroups: [""] - resources: ["services/proxy"] - resourceNames: ["heapster", "http:heapster:", "https:heapster:"] - verbs: ["get"] - - apiVersion: rbac.authorization.k8s.io/v1 - kind: RoleBinding - metadata: - labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard-minimal - namespace: garden-system - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: kubernetes-dashboard-minimal - subjects: - - kind: ServiceAccount - name: kubernetes-dashboard - namespace: garden-system - # ------------------- Dashboard Deployment ------------------- # - - kind: Deployment - apiVersion: apps/v1 - metadata: - labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard - namespace: garden-system - spec: - replicas: 1 - revisionHistoryLimit: 10 - selector: - matchLabels: - k8s-app: kubernetes-dashboard - template: - metadata: - labels: - k8s-app: kubernetes-dashboard - spec: - containers: - - name: kubernetes-dashboard - image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.2 - ports: - - containerPort: 8443 - protocol: TCP - args: - - --auto-generate-certificates - # Uncomment the following line to manually specify Kubernetes API server Host - # If not specified, Dashboard will attempt to auto discover the API server and connect - # to it. Uncomment only if the default does not work. - # - --apiserver-host=http://my-address:port - volumeMounts: - - name: kubernetes-dashboard-certs - mountPath: /certs - # Create on-disk volume to store exec logs - - mountPath: /tmp - name: tmp-volume - livenessProbe: - httpGet: - scheme: HTTPS - path: / - port: 8443 - initialDelaySeconds: 30 - timeoutSeconds: 30 - volumes: - - name: kubernetes-dashboard-certs - secret: - secretName: kubernetes-dashboard-certs - - name: tmp-volume - emptyDir: {} - serviceAccountName: kubernetes-dashboard - # Comment the following tolerations if Dashboard must not be deployed on master - tolerations: - - key: node-role.kubernetes.io/master - effect: NoSchedule - # ------------------- Dashboard Service ------------------- # - - kind: Service - apiVersion: v1 - metadata: - labels: - k8s-app: kubernetes-dashboard - name: dashboard - namespace: garden-system - spec: - type: NodePort - ports: - - port: 443 - nodePort: 32005 - targetPort: 8443 - selector: - k8s-app: kubernetes-dashboard + type: helm + chart: stable/kubernetes-dashboard + parameters: + ingress.enabled: true + ingress.hosts: [dashboard.local.sys.garden]