Skip to content

Commit

Permalink
fix(kubeconfig): accept relative and absolute paths (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
raszi authored and silasbw committed Nov 8, 2017
1 parent d8b46cb commit 3cbf9cf
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 6 deletions.
35 changes: 29 additions & 6 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const caPath = '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt';
const tokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token';
const namespacePath = '/var/run/secrets/kubernetes.io/serviceaccount/namespace';

function defaultConfigPath() {
const homeDir = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
return path.join(homeDir, '.kube', 'config');
}

/**
* Returns with in cluster config
* Based on: https://github.com/kubernetes/client-go/blob/124670e99da15091e13916f0ad4b2b2df2a39cd5/rest/config.go#L274
Expand Down Expand Up @@ -78,7 +83,7 @@ function fromKubeconfig(kubeconfig, current) {
if (user) {
if (user['client-certificate']) {
cert = fs.readFileSync(path.normalize(user['client-certificate']));
} else if (user && user['client-certificate-data']) {
} else if (user['client-certificate-data']) {
cert = Buffer.from(user['client-certificate-data'], 'base64').toString();
}

Expand Down Expand Up @@ -113,12 +118,30 @@ function fromKubeconfig(kubeconfig, current) {

module.exports.fromKubeconfig = fromKubeconfig;

function mapCertificates(cfgPath, config) {
const configDir = path.dirname(cfgPath);

config.clusters.filter(cluster => cluster.cluster['certificate-authority']).forEach(cluster => {
cluster.cluster['certificate-authority'] = path.resolve(configDir, cluster.cluster['certificate-authority']);
});

config.users.filter(user => user.user['client-certificate']).forEach(user => {
user.user['client-certificate'] = path.resolve(configDir, user.user['client-certificate']);
});

config.users.filter(user => user.user['client-key']).forEach(user => {
user.user['client-key'] = path.resolve(configDir, user.user['client-key']);
});

return config;
}

function loadKubeconfig(cfgPath) {
cfgPath = cfgPath || path.join(
process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'],
'.kube',
'config');
return yaml.safeLoad(fs.readFileSync(cfgPath));
cfgPath = cfgPath || defaultConfigPath();

const config = yaml.safeLoad(fs.readFileSync(cfgPath));

return mapCertificates(cfgPath, config);
}

module.exports.loadKubeconfig = loadKubeconfig;
65 changes: 65 additions & 0 deletions test/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const assume = require('assume');
const sinon = require('sinon');
const fs = require('fs');
const yaml = require('js-yaml');

const config = require('../lib/config');

Expand Down Expand Up @@ -130,6 +131,70 @@ describe('Config', () => {
assume(args.cert).equals('client-certificate');
});

it('handles relative and absolute certs and keys', () => {
const kubeconfig = {
'apiVersion': 'v1',
'kind': 'Config',
'preferences': {},
'current-context': 'foo-context',
'contexts': [
{
name: 'foo-context',
context: {
cluster: 'foo-cluster',
user: 'foo-user'
}
}
],
'clusters': [
{
name: 'foo-cluster',
cluster: {
'certificate-authority': 'ca.pem',
'server': 'https://192.168.42.121:8443'
}
}
],
'users': [
{
name: 'foo-user',
user: {
'client-certificate': '/absolute/path/client.cert',
'client-key': 'subdir/client.key'
}
}
]
};

const fsReadFileSync = sandbox.stub(fs, 'readFileSync');
const yamlSafeLoad = sandbox.stub(yaml, 'safeLoad');

fsReadFileSync
.withArgs(sinon.match(/config$/))
.returns('mock-config');

fsReadFileSync
.withArgs(sinon.match('/.kube/ca.pem'))
.returns('certificate-authority-data');

fsReadFileSync
.withArgs(sinon.match('/.kube/subdir/client.key'))
.returns('client-key-data');

fsReadFileSync
.withArgs('/absolute/path/client.cert')
.returns('client-certificate-data');

yamlSafeLoad
.withArgs('mock-config')
.returns(kubeconfig);

const args = config.fromKubeconfig();
assume(args.ca).equals('certificate-authority-data');
assume(args.key).equals('client-key-data');
assume(args.cert).equals('client-certificate-data');
});

it('handles token', () => {
const kubeconfig = {
'apiVersion': 'v1',
Expand Down

0 comments on commit 3cbf9cf

Please sign in to comment.