kubernetes-client
Advanced tools
Comparing version 8.2.1 to 8.3.0
'use strict' | ||
const { convertKubeconfig } = require('./config') | ||
const deprecate = require('depd')('kubernetes-client') | ||
const JSONStream = require('json-stream') | ||
@@ -103,12 +105,22 @@ const pump = require('pump') | ||
this.requestOptions = options.request || {} | ||
let convertedOptions | ||
if (!options.kubeconfig) { | ||
deprecate('Request() without a .kubeconfig option, see ' + | ||
'https://github.com/godaddy/kubernetes-client/blob/master/merging-with-kubernetes.md') | ||
convertedOptions = options | ||
} else { | ||
convertedOptions = convertKubeconfig(options.kubeconfig) | ||
} | ||
this.requestOptions.qsStringifyOptions = { indices: false } | ||
this.requestOptions.baseUrl = options.url | ||
this.requestOptions.ca = options.ca | ||
this.requestOptions.cert = options.cert | ||
this.requestOptions.key = options.key | ||
if ('insecureSkipTlsVerify' in options) { | ||
this.requestOptions.strictSSL = !options.insecureSkipTlsVerify | ||
this.requestOptions.baseUrl = convertedOptions.url | ||
this.requestOptions.ca = convertedOptions.ca | ||
this.requestOptions.cert = convertedOptions.cert | ||
this.requestOptions.key = convertedOptions.key | ||
if ('insecureSkipTlsVerify' in convertedOptions) { | ||
this.requestOptions.strictSSL = !convertedOptions.insecureSkipTlsVerify | ||
} | ||
if ('timeout' in options) { | ||
this.requestOptions.timeout = options.timeout | ||
if ('timeout' in convertedOptions) { | ||
this.requestOptions.timeout = convertedOptions.timeout | ||
} | ||
@@ -119,7 +131,7 @@ | ||
} | ||
if (options.auth) { | ||
this.requestOptions.auth = options.auth | ||
if (options.auth.provider) { | ||
this.requestOptions.auth = options.auth.request | ||
this.authProvider = options.auth.provider | ||
if (convertedOptions.auth) { | ||
this.requestOptions.auth = convertedOptions.auth | ||
if (convertedOptions.auth.provider) { | ||
this.requestOptions.auth = convertedOptions.auth.request | ||
this.authProvider = convertedOptions.auth.provider | ||
} | ||
@@ -126,0 +138,0 @@ } |
@@ -7,5 +7,10 @@ /* eslint-env mocha */ | ||
const KubeConfig = require('../../lib/config') | ||
const Request = require('./client') | ||
const url = 'http://mock.kube.api' | ||
const kubeconfig = new KubeConfig() | ||
kubeconfig.loadFromClusterAndUser( | ||
{ name: 'cluster', server: url }, | ||
{ name: 'user' }) | ||
@@ -19,3 +24,3 @@ describe('lib.backends.request', () => { | ||
const backend = new Request({ url }) | ||
const backend = new Request({ kubeconfig }) | ||
backend.http({ | ||
@@ -22,0 +27,0 @@ method: 'GET', |
@@ -56,2 +56,111 @@ 'use strict' | ||
function convertKubeconfig (kubeconfig) { | ||
const context = kubeconfig.getCurrentContext() | ||
const cluster = kubeconfig.getCurrentCluster() | ||
const user = kubeconfig.getCurrentUser() | ||
const namespace = context.namespace | ||
let ca | ||
let insecureSkipTlsVerify = false | ||
if (cluster) { | ||
if (cluster.caFile) { | ||
ca = fs.readFileSync(path.normalize(cluster.caFile)) | ||
} else if (cluster.caData) { | ||
ca = Buffer.from(cluster.caData, 'base64').toString() | ||
} | ||
insecureSkipTlsVerify = cluster.skipTLSVerify | ||
} | ||
let cert | ||
let key | ||
let auth = {} | ||
if (user) { | ||
if (user.certFile) { | ||
cert = fs.readFileSync(path.normalize(user.certFile)) | ||
} else if (user.certData) { | ||
cert = Buffer.from(user.certData, 'base64').toString() | ||
} | ||
if (user.keyFile) { | ||
key = fs.readFileSync(path.normalize(user.keyFile)) | ||
} else if (user.keyData) { | ||
key = Buffer.from(user.keyData, 'base64').toString() | ||
} | ||
if (user.token) { | ||
auth.bearer = user.token | ||
} | ||
if (user.authProvider) { | ||
const config = user.authProvider.config | ||
// if we can't determine the type, just fail later (or don't refresh). | ||
let type = null | ||
let token = null | ||
if (config['cmd-path']) { | ||
type = 'cmd' | ||
token = config['access-token'] | ||
} else if (config['idp-issuer-url']) { | ||
type = 'openid' | ||
token = config['id-token'] | ||
} | ||
// If we have just an access-token, allow that... will expire later though. | ||
if (config['access-token'] && !type) { | ||
token = config['access-token'] | ||
} | ||
auth = { | ||
request: { | ||
bearer: token | ||
}, | ||
provider: { | ||
config, | ||
type | ||
} | ||
} | ||
} | ||
if (user.exec) { | ||
const env = {} | ||
if (user.exec.env) { | ||
user.exec.env.forEach(variable => { | ||
env[variable.name] = variable.value | ||
}) | ||
} | ||
let args = '' | ||
if (user.exec.args) { | ||
args = user.exec.args.join(' ') | ||
} | ||
auth = { | ||
provider: { | ||
type: 'cmd', | ||
config: { | ||
'cmd-args': args, | ||
'cmd-path': user.exec.command, | ||
'token-key': 'status.token', | ||
'cmd-env': env | ||
} | ||
} | ||
} | ||
} | ||
if (user.username) auth.user = user.username | ||
if (user.password) auth.pass = user.password | ||
} | ||
return { | ||
url: cluster.server, | ||
auth: Object.keys(auth).length ? auth : null, | ||
ca, | ||
insecureSkipTlsVerify, | ||
namespace, | ||
cert, | ||
key | ||
} | ||
} | ||
module.exports.convertKubeconfig = convertKubeconfig | ||
// | ||
@@ -58,0 +167,0 @@ // Accept a manually specified current-context to take precedence over |
@@ -7,2 +7,3 @@ /* eslint no-process-env: 0 */ | ||
const fs = require('fs') | ||
const k8s = require('@kubernetes/client-node') | ||
const sinon = require('sinon') | ||
@@ -24,68 +25,8 @@ const yaml = require('js-yaml') | ||
describe('getInCluster', () => { | ||
beforeEach(() => { | ||
process.env.KUBERNETES_SERVICE_HOST = 'myhost' | ||
process.env.KUBERNETES_SERVICE_PORT = 443 | ||
}) | ||
it('should return with in-cluster config', () => { | ||
const fsReadFileSync = sandbox.stub(fs, 'readFileSync') | ||
fsReadFileSync | ||
.withArgs('/var/run/secrets/kubernetes.io/serviceaccount/ca.crt') | ||
.returns('my-ca') | ||
fsReadFileSync | ||
.withArgs('/var/run/secrets/kubernetes.io/serviceaccount/token') | ||
.returns('my-token') | ||
fsReadFileSync | ||
.withArgs('/var/run/secrets/kubernetes.io/serviceaccount/namespace') | ||
.returns('my-namespace') | ||
const configInCluster = config.getInCluster() | ||
expect(configInCluster).eqls({ | ||
auth: { bearer: 'my-token' }, | ||
ca: 'my-ca', | ||
namespace: 'my-namespace', | ||
url: 'https://myhost:443' | ||
}) | ||
}) | ||
afterEach(() => { | ||
delete process.env.KUBERNETES_SERVICE_HOST | ||
delete process.env.KUBERNETES_SERVICE_PORT | ||
}) | ||
}) | ||
describe('.loadKubeconfig', () => { | ||
const cfgPaths = [ | ||
'./backends/request/config.test/fixtures/kube-fixture.yml', | ||
'./backends/request/config.test/fixtures/kube-fixture-two.yml' | ||
] | ||
it('supports multiple config files', () => { | ||
const args = config.loadKubeconfig(cfgPaths) | ||
expect(args.contexts[0].name).equals('foo-context-1') | ||
expect(args.contexts[1].name).equals('foo-ramp-up') | ||
}) | ||
it('supports multiple config files in KUBECONFIG', () => { | ||
const delimiter = process.platform === 'win32' ? ';' : ':' | ||
process.env.KUBECONFIG = cfgPaths.join(delimiter) | ||
const args = config.loadKubeconfig() | ||
expect(args.contexts[0].name).equals('foo-context-1') | ||
expect(args.contexts[1].name).equals('foo-ramp-up') | ||
delete process.env.KUBECONFIG | ||
}) | ||
}) | ||
describe('.fromKubeconfig', () => { | ||
it('handles username and password', () => { | ||
const kubeconfig = { | ||
describe('.convertKubeconfig', () => { | ||
it('handles basic KubeConfig conversion', () => { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
'kind': 'Config', | ||
'preferences': {}, | ||
'current-context': 'foo-context', | ||
@@ -118,10 +59,12 @@ 'contexts': [ | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
expect(args.auth.user).equals('foo-user') | ||
expect(args.auth.pass).equals('foo-password') | ||
})) | ||
const covertedOptions = config.convertKubeconfig(kubeconfig) | ||
expect(covertedOptions.url).to.equal('https://192.168.42.121:8443') | ||
expect(covertedOptions.auth.user).to.equal('foo-user') | ||
expect(covertedOptions.auth.pass).to.equal('foo-password') | ||
}) | ||
it('handles base64 encoded certs and keys', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -158,4 +101,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.ca).equals('certificate-authority-data') | ||
@@ -167,3 +110,4 @@ expect(args.key).equals('client-key') | ||
it('handles relative and absolute certs and keys', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -200,3 +144,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
})) | ||
kubeconfig.makePathsAbsolute('/.kube') | ||
@@ -226,3 +171,3 @@ const fsReadFileSync = sandbox.stub(fs, 'readFileSync') | ||
const args = config.fromKubeconfig() | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.ca).equals('certificate-authority-data') | ||
@@ -234,3 +179,4 @@ expect(args.key).equals('client-key-data') | ||
it('handles token', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -265,4 +211,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.auth.bearer).equals('foo-token') | ||
@@ -272,3 +218,4 @@ }) | ||
it('handles auth-provider.config.access-token', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -307,4 +254,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.auth.request.bearer).equals('foo-token') | ||
@@ -314,3 +261,4 @@ }) | ||
it('handles auth-provider.config.idp-issuer-url', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -349,4 +297,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.auth.provider.type).equals('openid') | ||
@@ -356,3 +304,4 @@ }) | ||
it('handles auth-provider.config.cmd-path', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -392,4 +341,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.auth.provider.type).equals('cmd') | ||
@@ -403,3 +352,4 @@ }) | ||
const envValue = 'foo-env-value' | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -441,4 +391,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.auth.provider.type).equals('cmd') | ||
@@ -452,3 +402,4 @@ expect(args.auth.provider.config['cmd-args']).equals(cmdArgs.join(' ')) | ||
const command = 'foo-command' | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -485,4 +436,4 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig) | ||
})) | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.auth.provider.type).equals('cmd') | ||
@@ -495,3 +446,4 @@ expect(args.auth.provider.config['cmd-args']).equals('') | ||
it('handles manually specified current-context', () => { | ||
const kubeconfig = { | ||
const kubeconfig = new k8s.KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify({ | ||
'apiVersion': 'v1', | ||
@@ -539,21 +491,8 @@ 'kind': 'Config', | ||
] | ||
} | ||
const args = config.fromKubeconfig(kubeconfig, 'foo-context-2') | ||
})) | ||
kubeconfig.setCurrentContext('foo-context-2') | ||
const args = config.convertKubeconfig(kubeconfig) | ||
expect(args.url).equals('https://192.168.42.122:8443') | ||
}) | ||
it('load kubeconfig from provided path', () => { | ||
const args = config.fromKubeconfig('./backends/request/config.test/fixtures/kube-fixture.yml') | ||
expect(args.url).equals('https://192.168.42.121:8443') | ||
}) | ||
it('load kubeconfig from provided array of paths', () => { | ||
const cfgPaths = [ | ||
'./backends/request/config.test/fixtures/kube-fixture.yml', | ||
'./backends/request/config.test/fixtures/kube-fixture-two.yml' | ||
] | ||
const args = config.fromKubeconfig(cfgPaths) | ||
expect(args.url).equals('https://192.168.42.121:8443') | ||
}) | ||
}) | ||
}) |
@@ -5,2 +5,11 @@ # Changelog | ||
## [8.3.0](https://github.com/godaddy/kubernetes-client/compare/8.2.1...8.3.0) (2019-06-25) | ||
### Features | ||
* **KubeConfig:** switch to using `KubeConfig` for config handling ([#506](https://github.com/godaddy/kubernetes-client/issues/506)) ([cb94f02](https://github.com/godaddy/kubernetes-client/commit/cb94f02)) | ||
### [8.2.1](https://github.com/godaddy/kubernetes-client/compare/8.2.0...8.2.1) (2019-06-22) | ||
@@ -7,0 +16,0 @@ |
@@ -7,3 +7,4 @@ const deprecate = require('depd')('kubernetes-client') | ||
alias: require('./alias'), | ||
config: require('../backends/request/config') | ||
config: require('../backends/request/config'), | ||
KubeConfig: require('./config') | ||
} | ||
@@ -10,0 +11,0 @@ |
@@ -29,2 +29,3 @@ 'use strict' | ||
const fs = require('fs') | ||
const KubeConfig = require('./config') | ||
const path = require('path') | ||
@@ -201,3 +202,5 @@ const zlib = require('zlib') | ||
} else { | ||
backend = new Request(Request.config.fromKubeconfig()) | ||
const kubeconfig = new KubeConfig() | ||
kubeconfig.loadFromDefault() | ||
backend = new Request({ kubeconfig }) | ||
} | ||
@@ -204,0 +207,0 @@ } |
{ | ||
"name": "kubernetes-client", | ||
"version": "8.2.1", | ||
"version": "8.3.0", | ||
"description": "Simplified Kubernetes API client.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -27,4 +27,5 @@ # kubernetes-client | ||
let kubernetes-client load the file automatically through the `KUBECONFIG` | ||
env | ||
let kubernetes-client configure automatically by trying the `KUBECONFIG` | ||
environment variable first, then `~/.kube/config`, then an in-cluster | ||
service account, and lastly settling on a default proxy configuration: | ||
@@ -38,30 +39,38 @@ ```js | ||
```js | ||
const { KubeConfig } = require('kubernetes-client') | ||
const kubeconfig = new KubeConfig() | ||
kubeconfig.loadFromFile('~/some/path') | ||
const Request = require('kubernetes-client/backends/request') | ||
const backend = new Request(Request.config.fromKubeconfig('~/some/path')) | ||
const backend = new Request({ kubeconfig }) | ||
const client = new Client({ backend, version: '1.13' }) | ||
``` | ||
provide a kubeconfig object from memory: | ||
provide a configuration object from memory: | ||
```js | ||
// Should match the kubeconfig file format exactly | ||
const kubeconfig = { | ||
apiVersion: 'v1', | ||
clusters: [], | ||
contexts: [], | ||
'current-context': '', | ||
kind: 'Config', | ||
users: [] | ||
const config = { | ||
apiVersion: 'v1', | ||
clusters: [], | ||
contexts: [], | ||
'current-context': '', | ||
kind: 'Config', | ||
users: [] | ||
} | ||
const { KubeConfig } = require('kubernetes-client') | ||
const kubeconfig = new KubeConfig() | ||
kubeconfig.loadFromString(JSON.stringify(config)) | ||
const Request = require('kubernetes-client/backends/request') | ||
const backend = new Request(Request.config.fromKubeconfig(kubeconfig)) | ||
const backend = new Request({ kubeconfig }) | ||
const client = new Client({ backend, version: '1.13' }) | ||
``` | ||
and you can also specify the kubeconfig context by passing it as the | ||
second argument to `fromKubeconfig()`: | ||
and you can also specify the context by setting it in the `kubeconfig` | ||
object: | ||
```js | ||
kubeconfig.setCurrentContext('dev') | ||
``` | ||
const config = Request.config.fromKubeconfig(null, 'dev') | ||
``` | ||
@@ -68,0 +77,0 @@ You can also elide the `.version` and pass an OpenAPI specification: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1471378
35
8539
227
19